WPF学习 - 动画基础(2)

上一篇文章粗略的介绍了一下Animation类。本篇介绍一下Storyboard。

Storyboard,姑且翻译成“故事板”吧。实际上它是一个Animation对象的容器,可以容纳多个Animation对象,并进行同意的管理,如播放、暂停等。

最重要的一点,Storyboard可以在xaml中定义。

1.在xaml中使用Storyboard

例如上一篇文章中创建了一个简单的动画:鼠标点击的时候,btn(Button类型)的宽度由当前值变到到100。

复制代码
<!-- xaml代码 -->        
<Button Name="btn" Content="Click Me" HorizontalAlignment="Left" VerticalAlignment="Top" 
                Click="btn_MouseEnter"/>

// 后台代码
private void btn_MouseEnter(object sender, RoutedEventArgs e)
{
    DoubleAnimation widthAnimation = new()
    {
        From = btn.ActualWidth,
        To = 100,
        Duration = new Duration(TimeSpan.FromMilliseconds(1000))       // 持续1s钟
    };

    // 开始动画:指定要应用动画的属性
    btn.BeginAnimation(Button.WidthProperty,widthAnimation);            
}
复制代码

这段代码可以直接在xaml中定义。代码如下:

复制代码
<Button Name="btn" Content="Click Me" HorizontalAlignment="Left" VerticalAlignment="Top">
    <Button.Triggers>
        <EventTrigger RoutedEvent="{x:Static Button.MouseEnterEvent}">
            <BeginStoryboard Name="sizeStoryboard">
                <Storyboard Storyboard.TargetName="btn" Storyboard.TargetProperty="Width">
                    <DoubleAnimation From="{Binding Path=ActualWidth,ElementName=btn}" To="100" Duration="0:0:1" Storyboard.TargetName="btn" Storyboard.TargetProperty="Width"/>
                    <DoubleAnimation From="{Binding Path=ActualHeight,ElementName=btn}" To="50" Duration="0:0:1" Storyboard.TargetName="btn" Storyboard.TargetProperty="Height"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
     <!--下面这个触发器,只是为了演示效果-->
        <EventTrigger RoutedEvent="{x:Static Button.MouseLeaveEvent}">
            <!--停止Storyboard:属性值会回到原始状态-->
            <StopStoryboard BeginStoryboardName="sizeStoryboard" />
            <!--暂停Storyboard-->
            <PauseStoryboard BeginStoryboardName="sizeStoryboard"/>
            <!--继续Storyboard:继续已经暂定的Storyboard-->
            <ResumeStoryboard BeginStoryboardName="sizeStoryboard"/>
        </EventTrigger>
    </Button.Triggers>
</Button>
复制代码

备注:

  1)只有在Triggers中触发Storyboard。这里使用了BeginStoryboard,表示开始播放Storyboard。

  2)Storyboard定义了三个附件属性:Target、TargetName、TargetProperty。其中Target、TargetName属性用来表示对哪个DependencyObject应用动画,前者多在后台代码中使用(因为可以很方便的通过元素的name属性找到元素),后台多用在xaml中。TargetProperty属性表示对目标元素的哪个属性应用动画。

  3)如果多个动画都是应用同一个元素,同一个属性,可以将Target、TargetName、TargetProperty等附加属性写在Storyboard中。

2.在后台代码中应用Storyboard

  上面的代码等效于如下代码(不考虑StopStoryboard 、PauseStoryboard 、ResumeStoryboard ):

复制代码
<!--xaml代码-->
<Button Name="btn" Content="Click Me" HorizontalAlignment="Left" VerticalAlignment="Top" Click="btn_MouseEnter"/>

// 后台代码
private void btn_MouseEnter(object sender, RoutedEventArgs e)
{
    // 创建动画
    DoubleAnimation widthAnimation = new()
    {
        From = btn.ActualWidth,
        To = 100,
        Duration = new Duration(TimeSpan.FromSeconds(1))
    };
    widthAnimation.SetValue(Storyboard.TargetProperty, btn);
    widthAnimation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(Button.WidthProperty));

    DoubleAnimation heightAnimation = new()
    {
        From = btn.ActualHeight,
        To = 50,
        Duration = new Duration(TimeSpan.FromSeconds(1))
    };
    heightAnimation.SetValue(Storyboard.TargetProperty, btn);
    heightAnimation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(Button.HeightProperty));

    // 创建Storyboard
    Storyboard sb = new();
    sb.Children.Add(widthAnimation);
    sb.Children.Add(heightAnimation);
    BeginStoryboard(sb);
}
复制代码

备注:

  1)因为Animation需要知道自己应用到哪个对象的哪个属性上,因此需要使用SetValue()方法来设置附加属性Storyboard.TargetPropert、Storyboard.TargetPropertyProperty。

  2)在设置Storyboard.TargetPropertyProperty附加属性的值时,不能直接给Button.WidthProperty,而应该给new PropertyPath(Button.WidthProperty)。

  3)播放Storyboard是通过BeginStoryboard()方法。这个方法在FrameworkElement中定义,因此任何继承自改类的对象,都可以调用动画。但是,到底是谁调用的,无所谓。例如本例中,是通过this(也就是Window类的实例)调用的。也可以使用btn(Button类的实例)来调用。

 

暂时介绍到这里吧。这两篇文章也仅仅是开个头,更多应用,还需要各位自己深入学习。

以上为本人自己的学习心得,仅做记录,也帮助初学者解惑。如有错误,还请大神指正。

 

posted @   卓尔不设凡  阅读(519)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示