C# 在 WPF 背后的代码中创建故事板

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15900627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 18:22:05  来源:igfitidea点击:

Creating Storyboard in code behind in WPF

c#.netwpfanimationeventtrigger

提问by Raj

The following code is working fine.

以下代码工作正常。

<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Duration="0:0:.8" Storyboard.TargetProperty="Left" From="1920" To="0" AccelerationRatio=".1"/>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</Window.Triggers>

But in this Fromand Tovalues are static. I need to pass the values dynamically based system resolution. So i need it to be created in code behind. Is it possible to do ?

但在这个FromTo值是静态的。我需要基于系统分辨率动态传递值。所以我需要在后面的代码中创建它。有可能吗?

How to convert it to codebehind?

如何将其转换为代码隐藏?

采纳答案by Terry

When working in code, you don't need Storyboard really, just animations for basic things, like you show in your question. I made a little sample to show how easy it works.

使用代码时,您实际上并不需要 Storyboard,只需要基本内容的动画,就像您在问题中所展示的那样。我制作了一个小示例来展示它的工作方式。

This is the complete code behind of the mainwindow:

这是主窗口背后的完整代码:

namespace WpfCSharpSandbox
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            WidenObject(150, TimeSpan.FromSeconds(1));
        }

        private void WidenObject(int newWidth, TimeSpan duration)
        {
            DoubleAnimation animation = new DoubleAnimation(newWidth, duration);
            rctMovingObject.BeginAnimation(Rectangle.WidthProperty, animation);
        }
    }
}

This is how the XAML looks like:

这是 XAML 的样子:

<Window x:Class="WpfCSharpSandbox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Sandbox" Height="350" Width="525">
    <Grid Background="#333333">
        <Rectangle x:Name="rctMovingObject" Fill="LimeGreen" Width="50" Height="50"/>
    </Grid>
</Window>

Put this in a WPF app and see how it works, experiment with it and try other animations/properties.

把它放在一个 WPF 应用程序中,看看它是如何工作的,试验它并尝试其他动画/属性。

回答by sthotakura

Adding djerry's comment sample code would look like this:

添加 djerry 的注释示例代码如下所示:

var anim = new DoubleAnimation {
                                From = 1920, 
                                To = 1, 
                               };

wnd.BeginAnimation(Window.LeftProperty, anim); 

and you would have to have this code in window loaded event handler. Hope this helps.

并且您必须在窗口加载的事件处理程序中使用此代码。希望这可以帮助。

回答by Martin Schneider

The question's example code was about animating the Window.Leftproperty and I was looking for exact that case, but the given answer does work for an one-time use-case only.
Specifically: If the animation has been performed and the Window is then moved manually via drag&drop, the same animation procedure will not work again as desired. The animation will always use the end-coordinates of the recent animation run.
So if you moved the window, it will jump back before starting the new animation:

问题的示例代码是关于为Window.Left属性设置动画的,我正在寻找确切的案例,但给定的答案仅适用于一次性用例。
具体来说:如果动画已经执行,然后通过拖放手动移动窗口,则相同的动画过程将无法按需要再次运行。动画将始终使用最近运行的动画的结束坐标。
所以如果你移动了窗口,它会在开始新动画之前跳回来:

https://imgur.com/a/hxRCqm7

https://imgur.com/a/hxRCqm7

To solve that issue, it is required to remove any AnimationClockfrom the animated property after the animation is completed.

要解决该问题,需要AnimationClock在动画完成后从动画属性中删除任何内容。

That is done by using ApplyAnimationClockor BeginAnimationwith nullas the second parameter:

这是通过使用ApplyAnimationClockBeginAnimationwithnull作为第二个参数来完成的:

public partial class MainWindow : Window
{
    // [...]

    private void ButtonMove_Click(object sender, RoutedEventArgs e)
    {
        AnimateWindowLeft(500, TimeSpan.FromSeconds(1));
    }

    private void AnimateWindowLeft(double newLeft, TimeSpan duration)
    {
        DoubleAnimation animation = new DoubleAnimation(newLeft, duration);
        myWindow.Completed += AnimateLeft_Completed;
        myWindow.BeginAnimation(Window.LeftProperty, animation);
    }

    private void AnimateLeft_Completed(object sender, EventArgs e)
    {
        myWindow.BeginAnimation(Window.LeftProperty, null);
        // or
        // myWindow.ApplyAnimationClock(Window.LeftProperty, null);
    }
}

XAML:

XAML:

<Window x:Class="WpfAppAnimatedWindowMove.MainWindow"
        // [...]
        Name="myWindow">

Result:
https://imgur.com/a/OZEsP6t

结果:https:
//imgur.com/a/OZEsP6t

See also Remarks section of Microsoft Docs - HandoffBehavior Enum

另请参阅Microsoft Docs 的备注部分 - HandoffBehavior Enum