WPF:仿WIN7窗体打开关闭效果

WIN7系统里面有很多很炫的动画效果,今天来模仿一下最常见的窗体打开关闭时的动画效果,比如打开一窗体,顶部靠外倾斜,透明渐变显示,关闭窗口,则反之的效果。

先新建一窗体,因为有向前向后倾斜效果,为了省事,引用一DLL,3DTools。

也就是创建一个3D模型,然后对它添加动画。

讲一下用到3DTools 的地方。

先引用

xmlns:tool="clr-namespace:_3DTools;assembly=3DTools"
<Grid>
        <tool:Interactive3DDecorator ContainsInk="False">
            <Viewport3D x:Name="view" Opacity="0">
                <Viewport3D.Camera>
                    <PerspectiveCamera Position="0, 0.5, 3.2"/>
                </Viewport3D.Camera>
                
                <tool:InteractiveVisual3D
                                     Geometry="{StaticResource PlaneMesh}"
                                     Visual="{StaticResource Visual}" 
                                     IsBackVisible="False">
                    <tool:InteractiveVisual3D.Transform>
                        <Transform3DGroup>
                        <RotateTransform3D>
                            <RotateTransform3D.Rotation>
                                <AxisAngleRotation3D x:Name="axis" Angle="0" Axis="1 0 0" />
                            </RotateTransform3D.Rotation>
                        </RotateTransform3D>
                            <ScaleTransform3D x:Name="scale" ScaleX="1" ScaleY="1" ScaleZ="1"/>
                        </Transform3DGroup>
                    </tool:InteractiveVisual3D.Transform>
                </tool:InteractiveVisual3D>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <DirectionalLight Color="#FFFFFFFF"/>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
            </Viewport3D>
        </tool:Interactive3DDecorator>
    </Grid>

与普通的创建3D模型不同,在Viewport3D外面加上一层Interactive3DDecorator,便可以操作上面的控件,而不是仅仅当作Brush画上去的。

然后为InteractiveVisual3D设置属性,Geometry 就是上一节讲的MeshGeometry3D,这个是和普通的一样的

<!-- 3D Models -->
        <MeshGeometry3D x:Key="PlaneMesh" Positions="-1,2.5,0 -1,-1,0 1,-1,0 1,2.5,0" 
                        Normals="0 0 1, 0 0 1, 0 0 1, 0 0 1"
                        TextureCoordinates="0,0 0,1 1,1 1,0" 
                        TriangleIndices="0 1 2 2 3 0"/>

Visual就根据你的情况来设置了,什么样的UI就写什么Visual。

这里要说一下为了更好的效果要对窗体做下外观修改:

WindowStyle="None" WindowStartupLocation="CenterScreen" Background="Transparent" AllowsTransparency="True"

在Window 的属性里设置这些。

当然你也可以自定义控件,模仿得更像一下比如:

 下面就开始写动画了

<Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation From="0.75" To="1" Storyboard.TargetName="scale"
                                     Storyboard.TargetProperty="ScaleX" Duration="0:0:0.35"/>
                    <DoubleAnimation From="0.75" To="1" Storyboard.TargetName="scale"
                                     Storyboard.TargetProperty="ScaleY" Duration="0:0:0.35"/>
                    <DoubleAnimation From="13" To="0" Storyboard.TargetName="axis"
                                     Storyboard.TargetProperty="Angle" Duration="0:0:0.35"/>
                    <DoubleAnimation From="0" To="1" Storyboard.TargetName="view"
                                     Storyboard.TargetProperty="Opacity" Duration="0:0:0.35"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>

这个就是打开窗体时的动画,里面是对Opacity,ScaleTransform3D,AxisAngleRotation3D同时进行了动画,效果还不错。

然后就是关闭动画了

<!--Close Window Storyboard-->
        <Storyboard x:Key="closeStory">
            <DoubleAnimation From="1" To="0.75" Storyboard.TargetName="scale"
                                     Storyboard.TargetProperty="ScaleX" Duration="0:0:0.3"/>
            <DoubleAnimation From="1" To="0.75" Storyboard.TargetName="scale"
                                     Storyboard.TargetProperty="ScaleY" Duration="0:0:0.3"/>
            <DoubleAnimation From="0" To="-15" Storyboard.TargetName="axis"
                                     Storyboard.TargetProperty="Angle" Duration="0:0:0.25"/>
            <DoubleAnimation From="1" To="0" Storyboard.TargetName="view"
                                     Storyboard.TargetProperty="Opacity" Duration="0:0:0.3"/>
        </Storyboard>

上面的Geometry,Visual还有这个closeStory都是写在Window.Resources的。

那我们来写一下点击关闭按钮后的动画处理。

 先要为窗体添加一个关闭事件:

 Closing="window_Closing"

然后是在后台代码:

bool isclose = false;
        private void window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (!isclose)
            {
          //找到资源定义的故事板
Storyboard story
= this.Resources["closeStory"] as Storyboard; story.Completed += delegate { isclose = true; this.Close(); }; story.Begin(); e.Cancel = true; } }

声明一个bool变量,用来记录是否已进行完动画效果。
if isclose == false,

就找到资源定义的动画,让它Begin,不要忘了添加一个Completed事件。

重要的一点是,e.Cancel = true; 要写在 Begin 后面,否则会达不到效果。

然后就是当动画结束后触发Completed事件,为 isclose 赋值为 true。

再关闭一次窗体。就会又触发window_Closing。但是这次isclose == true,所以不执行括号内的代码,然后直接结束。

代码很简单,主要还是 3DTools 省了不少事,值得好好研究下。

 

posted @ 2012-05-27 10:37  Walsh  阅读(3619)  评论(10编辑  收藏  举报