WPF自学—模仿QQ窗体载入和关闭动画

来源:互联网 发布:windows下caffe安装 编辑:程序博客网 时间:2024/05/31 04:03

这两天把《WPF编程宝典》这本书的动画相关章节看完了,于是想写个小程序练练手,但是不知道写什么好。看书的时候虽然也把上面的案例照着敲了一遍,但是它们毕竟和实际应用有很大差别,想用到日常项目里也不知道从何下手。

刚好看到了一位网友 youngytj  分享的模仿QQ载入和关闭动画的文章,我就跟着学习模仿了一遍,下面来讲讲具体如何实现的。

首先分析下我想实现的效果:第一,我打开程序后它从上到下滚动逐渐显示出来。第二,我点击窗口的关闭按钮后,窗体由下而上滚动逐渐消失。

为了实现这种效果我们要把窗体的WindowStyle设为None,因为用默认窗体风格的话,动画是运行在一个带有边框的框架里面的,远不是我们想要的效果,如下图:

 

从上面还可以看到窗体动画运行的时候,未填充的部分显示黑色,这是因为窗体的AllowsTransparency属性为false的缘故。我们把AllowsTransparency设为true以后,窗体的工作区支持透明了,就不会有黑色出现了。

接下来我们要给窗体设置一个背景,这样运行才能看到效果,我设的背景是一个渐变画刷,上面是浅蓝色,下面是白色,代码如下:

<Style TargetType="Window" x:Key="MyWindowStyle">        <Setter Property="Background">            <Setter.Value>                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">                    <GradientStop Color="#428AC7" Offset="0"/>                    <GradientStop Color="White" Offset="1"/>                </LinearGradientBrush>            </Setter.Value>        </Setter></Style>

建议:为了规范点,我创建了一个资源字典MainResourceDictionary:本示例的所有样式是放在这里面的。

背景添加完以后我们需要给窗体添加一个透明掩码和展开、合并的动画,这也是本示例的关键部分。动画改变的就是这个透明掩码的偏移值和偏移的颜色。透明掩码如下:

<Window.OpacityMask>        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">            <GradientStop Offset="0" Color="Transparent"></GradientStop>            <GradientStop Offset="0" Color="Yellow"></GradientStop>        </LinearGradientBrush></Window.OpacityMask>

这个透明掩码也是一个渐变画刷组成的,它实现的是从上到下的垂直渐变。我自己测试之后发现,这个渐变画刷最关键的部分是指定第一个颜色为透明色,至于后面一种颜色设置成什么都无所谓,不知道为什么会这样。(因为是新手,我现在还只是“知其然”的阶段,如果哪位大神知道原因还请不吝赐教。)

动画的代码如下:

<Window.Resources>        <Storyboard x:Key="zhankai">            <DoubleAnimation From="0" To="1" Duration="0:0:0.5"                                 Storyboard.TargetName="MyWindow"                                 Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[0].Offset"/>            <DoubleAnimation From="0" To="1" BeginTime="0:0:0.1" Duration="0:0:0.4"                                 Storyboard.TargetName="MyWindow"                                 Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[1].Offset"/>            <ColorAnimation BeginTime="0:0:0.5" Duration="0:0:0" From="Transparent" To="Yellow" Storyboard.TargetName="MyWindow"                                 Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[0].Color"/>        </Storyboard>        <Storyboard x:Key="hebing" Completed="Storyboard_Completed">            <DoubleAnimation From="1" To="0" Duration="0:0:0.4"                                 Storyboard.TargetName="MyWindow"                                 Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[0].Offset"/>            <DoubleAnimation Duration="0:0:.3" BeginTime="0:0:0.1" From="1" To="0"                                 Storyboard.TargetName="MyWindow"                                 Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[1].Offset"/>            <ColorAnimation Duration="0" From="Yellow" To="Transparent" Storyboard.TargetName="MyWindow"                                 Storyboard.TargetProperty="(UIElement.OpacityMask).(GradientBrush.GradientStops)[1].Color"/>        </Storyboard>    </Window.Resources> 

动画添加完以后我们需要在事件触发器里调用它们,具体是哪两个事件呢?

我一开始想的是在Window.Loaded调用展开动画,在Button.Click事件里调用关闭动画,但是在展开的时候有一个问题。那就是Window.Loaded事件是加载完以后才执行的,这时候才调用动画给人的感觉就是窗体先弹出来,然后再回头由上而下逐渐滚动显示出来,这就有点凌乱了。

所以还是按照youngytj的方法,在窗体的构造函数里调用,这样就实现了从无到有逐渐显示的效果,代码如下:

 Storyboard storyBoard =(System.Windows.Media.Animation.Storyboard)MyWindow.Resources["zhankai"]; if (storyBoard != null) {     storyBoard.Begin(); }

 

关闭动画我们还是在Xaml里调用,代码如下:

 

<Window.Triggers>        <EventTrigger RoutedEvent="Button.Click">            <BeginStoryboard Storyboard="{StaticResource hebing}"></BeginStoryboard>        </EventTrigger></Window.Triggers>

现在基本上就实现了我们要的效果了,如下图:

 

以上就是全部的实现了,整体来说也没有什么难点。但我觉得对于我们新手来说最大的问题不是如何实现出这样的动画,而是大脑当中如何设计出这样的动画。比如我是看了youngytj 的文章才知道这个动画的原理,如果凭空让我设计其他动画的话我还是不知道如何下手,这是最头疼的,还是继续努力学习吧,争取早点脱离这种“只知其然而不知其所以然”的阶段。


源码已经上传,感兴趣的朋友可以去下载:

http://download.csdn.net/detail/u011014032/8207279

0 0
原创粉丝点击