Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WPF中设置渲染转换动画_C#_Wpf_Animation_Rendertransform - Fatal编程技术网

C# 在WPF中设置渲染转换动画

C# 在WPF中设置渲染转换动画,c#,wpf,animation,rendertransform,C#,Wpf,Animation,Rendertransform,我有一个关于C代码中WPF动画的问题 我有一个用于MouseWheel事件的处理程序函数。它只是检查你是“放大”还是“缩小”。只要看一下代码,这里最重要的一行是第四行,其中设置了RenderTransform private void ZoomPanCanvas_MouseWheel(object sender, MouseWheelEventArgs e) { var factor = (e.Delta > 0) ? (1.1) : (1 / 1.1);

我有一个关于C代码中WPF动画的问题
我有一个用于MouseWheel事件的处理程序函数。它只是检查你是“放大”还是“缩小”。只要看一下代码,这里最重要的一行是第四行,其中设置了RenderTransform

    private void ZoomPanCanvas_MouseWheel(object sender, MouseWheelEventArgs e) {
        var factor = (e.Delta > 0) ? (1.1) : (1 / 1.1);
        currrentScale = factor * currrentScale;
        mNetworkUI.RenderTransform = new ScaleTransform(currrentScale, currrentScale);
        var pos = e.GetPosition(mNetworkUI);
        mNetworkUI.Width = ZoomPanCanvas.ActualWidth / currrentScale;
        mNetworkUI.Height = ZoomPanCanvas.ActualHeight /currrentScale;
        var dummyTransform = new ScaleTransform(factor, factor, pos.X, pos.Y);
        var offSet = new Point(dummyTransform.Value.OffsetX, dummyTransform.Value.OffsetY);
        mNetworkUI.ViewModel.Network.SetTransformOffset(offSet);
    }
为了完整起见,我将函数的其余部分保留在代码中。
我想做的是设置渲染转换的动画

我已经尝试使用故事板(带有UIElement.RenderTransferormProperty集)。最好的结果是对RenderTransform进行了非动画的更改(但与代码中的第四行结果不同)

也许你能帮助我,我已经尝试了其他问题中的一些建议方法

编辑:

以下是非工作尝试,首先是上面的chenged代码:

    private void ZoomPanCanvas_MouseWheel(object sender, MouseWheelEventArgs e) {
        var factor = (e.Delta > 0) ? (1.1) : (1 / 1.1);
        currrentScale = factor * currrentScale;
        ///mNetworkUI.RenderTransform = new ScaleTransform(currrentScale, currrentScale);
        Helper.Animations.RenderTransformAnimation(mNetworkUI, new ScaleTransform(currrentScale, currrentScale));
        var pos = e.GetPosition(mNetworkUI);
        mNetworkUI.Width = ZoomPanCanvas.ActualWidth / currrentScale;
        mNetworkUI.Height = ZoomPanCanvas.ActualHeight /currrentScale;
        var dummyTransform = new ScaleTransform(factor, factor, pos.X, pos.Y);
        var offSet = new Point(dummyTransform.Value.OffsetX, dummyTransform.Value.OffsetY);
        mNetworkUI.ViewModel.Network.SetTransformOffset(offSet);
    }
它遵循静态辅助函数:

    public static void RenderTransformAnimation(FrameworkElement element, Transform newTransform) {
        MatrixAnimationUsingKeyFrames anim = new MatrixAnimationUsingKeyFrames();
        var key1 = new DiscreteMatrixKeyFrame(element.RenderTransform.Value, KeyTime.FromPercent(0));
        var key2 = new DiscreteMatrixKeyFrame(newTransform.Value, KeyTime.FromPercent(1));

        Storyboard.SetTarget(anim, element.RenderTransform);
        Storyboard.SetTargetProperty(anim, new PropertyPath(UIElement.RenderTransformProperty));
        Storyboard sb = new Storyboard();
        sb.Children.Add(anim);
        sb.Duration = AnimationDuration;
        sb.Begin();
    }
它总是在sb.Begin()调用时抛出一个异常,告诉我我的“PropertyPath”有问题。我不知道怎么做。
我的意思是,没有办法直接创建“变形动画”,对吗?只有矩阵动画可用…

我在下面提供了一个
缩放变换的简单动画。为了提供一个“最小”示例,我只调整缩放;我不做任何基于鼠标位置的偏移计算。您应该能够从这里找到方向:

private void OnMouseWheel(object sender, MouseWheelEventArgs e)
{
    var factor = e.Delta > 0d ? 1.1d : 0.9d;

    var t = mNetworkUI.RenderTransform as ScaleTransform;
    if (t == null)
    {
        mNetworkUI.RenderTransform = t = new ScaleTransform(1d, 1d)
                                         {
                                             CenterX = 0.5d,
                                             CenterY = 0.5d
                                         };
    }

    var oldScale = (double)t.GetAnimationBaseValue(ScaleTransform.ScaleXProperty);
    var newScale = oldScale * factor;

    //
    // Make sure `GetAnimationBaseValue()` reflects the `To` value next time
    // (needed to calculate `oldScale`, and for the animation to infer `From`).
    //
    t.ScaleX = newScale;
    t.ScaleY = newScale;

    var animation = new DoubleAnimation
                    {
                        To = newScale,
                        Duration = TimeSpan.FromSeconds(0.5d),
                        DecelerationRatio = 0.5d,
                        FillBehavior = FillBehavior.Stop
                    };

    //
    // Use `HandoffBehavior.Compose` to transition more smoothly if an animation
    // is already in progress.
    //
    t.BeginAnimation(
        ScaleTransform.ScaleXProperty, 
        animation, 
        HandoffBehavior.Compose);

    t.BeginAnimation(
        ScaleTransform.ScaleYProperty,
        animation,
        HandoffBehavior.Compose);
}

如果你解释为什么显式设置
t.ScaleX=newScale
,你会得到+1。这会被动画覆盖,不是吗?顺便说一句,你不需要指定
oldScale
。动画可以解决这个问题。是的,动画会覆盖比例值,但仅在动画持续时间内。动画结束后,y您希望属性仍然具有
to
值。但是,是的,您可以只指定
to
值,或者只指定
From
值,然后让动画计算出另一个值。为什么不将这两个动画包装在一个故事板中?否则,这对我来说似乎是正确的。您当然可以使用故事板,我通常在协调时会这样做在这种情况下,我觉得这只是增加了一层复杂性。如果一个动画已经在进行中,则稍微调整一下答案以使事情变得平滑。