WPF案例(-)模拟Windows7 Win+Tab切换

    一个使用Wpf模拟Windows7 Win+Tab页面切换的小程序,使用快捷键Ctrl+Down或Ctrl+Up在示例程序各个页面元素之间滑动导航,在本例中,使用Viewport2DVisual3D宿主二维控件,在这里为方便示例,二维控件仅简单的使用了一个Image,以下是界面缩略图,有兴趣的朋友可以下载源码

 界面缩略图

    在建立本示例中的三维场景时,使用了Viewport3D,PerspectiveCamera,AmbientLight,Viewport2DVisual3D,RotateTransform3D,TranslateTransform3D,ScaleTransform3D等元素,下面分别简单说明一下这些元素在三维场景中分别充当了什么角色

1.Viewport3D :Viewport3D是一个2D可视化元素,它是在2D场景中封装3D元素的容器控件,具有两个重要的属性

public Camera Camera { getset; }
public Visual3DCollection Children { get; }

   Camera 为3D场景指定观察者所处的位置

   Children 表示Viewport3D的所有3D子控件的集合类

2.PerspectiveCamera 表示透视投影摄像机,在本示例中使用它对3D场景进行透视投影

3.AmbientLight 灯光用来照亮3D场景

4.Viewport2DVisual3D 在3D场景中呈现可交互的2D控件,在本示例中就使用了6个Viewport2DVisual3D元素分别呈现了六幅Image

5.RotateTransform3D 对3D元素应用旋转,本示例中使用它对Viewport2DVisual3D进行Y轴45度旋转的模型变换

6.TranslateTransform3D 对3D元素应用平移,本示例中使用它对Viewport2DVisual3D分别进行X,Y,Z平移的模型变换

7.ScaleTransform3D 对3D元素应用拉伸缩放,本示例中使用它对Viewport2DVisual3D进行了X,Y的拉伸模型变换

以下为定义3D场景的XAML代码

3D场景 
  1  <Viewport3D  x:Name="Viewport3D" RenderOptions.EdgeMode="Aliased" ClipToBounds="False" 
                               IsHitTestVisible="False">
  2             <Viewport3D.Camera>
  3                 <PerspectiveCamera Position="0,0,8"  />
  4             </Viewport3D.Camera>
  5             <Viewport2DVisual3D x:Name="viewport2DVisual3D0" Geometry="{StaticResource geometry}"  
                                Material="{StaticResource material}" >
  6                 <Viewport2DVisual3D.Transform>
  7                     <Transform3DGroup>
  8                         <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
  9                             <RotateTransform3D.Rotation>
 10                                 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
 11                             </RotateTransform3D.Rotation>
 12                         </RotateTransform3D>
 13                         <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/>
 14                         <ScaleTransform3D CenterX="0" CenterY="0" 
                                   CenterZ="0" ScaleX="1.5" ScaleY="1" />
 15                     </Transform3DGroup>
 16                 </Viewport2DVisual3D.Transform>
 17                 <Viewport2DVisual3D.Visual>
 18                     <Image Source="Images\051027nature01.jpg" Stretch="Fill"
                               HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
 19                 </Viewport2DVisual3D.Visual>
 20             </Viewport2DVisual3D>
 21             <Viewport2DVisual3D x:Name="viewport2DVisual3D1" Geometry="{StaticResource geometry}" 
                              Material="{StaticResource material}">
 22                 <Viewport2DVisual3D.Transform>
 23                     <Transform3DGroup>
 24                         <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
 25                             <RotateTransform3D.Rotation>
 26                                 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
 27                             </RotateTransform3D.Rotation>
 28                         </RotateTransform3D>
 29                         <TranslateTransform3D OffsetX="-1" OffsetY="1" OffsetZ="-4"/>
 30                         <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0" 
                                   ScaleX="1.5" ScaleY="1" />
 31                     </Transform3DGroup>
 32                 </Viewport2DVisual3D.Transform>
 33                 <Viewport2DVisual3D.Visual>
 34                     <Image Source="Images\051027nature02.jpg" Stretch="Fill" 
                                      HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
 35                 </Viewport2DVisual3D.Visual>
 36             </Viewport2DVisual3D>
 37             <Viewport2DVisual3D x:Name="viewport2DVisual3D2" Geometry="{StaticResource geometry}"
                                     Material="{StaticResource material}">
 38                 <Viewport2DVisual3D.Transform>
 39                     <Transform3DGroup>
 40                         <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
 41                             <RotateTransform3D.Rotation>
 42                                 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
 43                             </RotateTransform3D.Rotation>
 44                         </RotateTransform3D>
 45                         <TranslateTransform3D OffsetX="-2" OffsetY="1.5" OffsetZ="-8"/>
 46                         <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0"
                                    ScaleX="1.5" ScaleY="1" />
 47                     </Transform3DGroup>
 48                 </Viewport2DVisual3D.Transform>
 49                 <Viewport2DVisual3D.Visual>
 50                     <Image Source="Images\11550549.jpg" Stretch="Fill" 
                                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
 51                 </Viewport2DVisual3D.Visual>
 52             </Viewport2DVisual3D>
 53             <Viewport2DVisual3D x:Name="viewport2DVisual3D3" Geometry="{StaticResource geometry}" 
                                Material="{StaticResource material}">
 54                 <Viewport2DVisual3D.Transform>
 55                     <Transform3DGroup>
 56                         <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
 57                             <RotateTransform3D.Rotation>
 58                                 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
 59                             </RotateTransform3D.Rotation>
 60                         </RotateTransform3D>
 61                         <TranslateTransform3D OffsetX="-3" OffsetY="1.5" OffsetZ="-12"/>
 62                         <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0" 
                                      ScaleX="1.5" ScaleY="1" />
 63                     </Transform3DGroup>
 64                 </Viewport2DVisual3D.Transform>
 65                 <Viewport2DVisual3D.Visual>
 66                     <Image Source="Images\11550556.jpg" Stretch="Fill" 
                             HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
 67                 </Viewport2DVisual3D.Visual>
 68             </Viewport2DVisual3D>
 69             <Viewport2DVisual3D x:Name="viewport2DVisual3D4" Geometry="{StaticResource geometry}"
                                             Material="{StaticResource material}">
 70                 <Viewport2DVisual3D.Transform>
 71                     <Transform3DGroup>
 72                         <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
 73                             <RotateTransform3D.Rotation>
 74                                 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
 75                             </RotateTransform3D.Rotation>
 76                         </RotateTransform3D>
 77                         <TranslateTransform3D OffsetX="-4" OffsetY="1.5" OffsetZ="-16"/>
 78                         <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0"
                                        ScaleX="1.5" ScaleY="1" />
 79                     </Transform3DGroup>
 80                 </Viewport2DVisual3D.Transform>
 81                 <Viewport2DVisual3D.Visual>
 82                     <Image Source="Images\11550560.jpg" Stretch="Fill" 
                                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
 83                 </Viewport2DVisual3D.Visual>
 84             </Viewport2DVisual3D>
 85             <Viewport2DVisual3D x:Name="viewport2DVisual3D5" Geometry="{StaticResource geometry}" 
                                      Material="{StaticResource material}">
 86                 <Viewport2DVisual3D.Transform>
 87                     <Transform3DGroup>
 88                         <RotateTransform3D CenterX="0" CenterY="0" CenterZ="0">
 89                             <RotateTransform3D.Rotation>
 90                                 <AxisAngleRotation3D Axis="0,1,0" Angle="35"/>
 91                             </RotateTransform3D.Rotation>
 92                         </RotateTransform3D>
 93                         <TranslateTransform3D OffsetX="-5" OffsetY="1.5" OffsetZ="-20"/>
 94                         <ScaleTransform3D CenterX="0" CenterY="0" CenterZ="0"
                                    ScaleX="1.5" ScaleY="1" />
 95                     </Transform3DGroup>
 96                 </Viewport2DVisual3D.Transform>
 97                 <Viewport2DVisual3D.Visual>
 98                     <Image Source="Images\051123Webshots05.jpg" Stretch="Fill" 
                                 HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
 99                 </Viewport2DVisual3D.Visual>
100             </Viewport2DVisual3D>
101             <ModelVisual3D>
102                 <ModelVisual3D.Content>
103                     <AmbientLight Color="White" />
104                 </ModelVisual3D.Content>
105             </ModelVisual3D>
106 </Viewport3D>

   通过以上的XAML语言定义了一个静态的3D场景,以下的代码实现将此3D场景支持动画效果,即模仿Windows7的Win+Tab切换特效

C#动画
  1         public void MoveCurrentToNext()
  2         {
  3             //向前移动,取Viewport3D的第一个Viewport2DVisual3为当前Viewport2DVisual3D
  4             var current = this.Viewport3D.Children[0];
  5             var child1 = this.Viewport3D.Children[1];
  6             var child2 = this.Viewport3D.Children[2];
  7             var child3 = this.Viewport3D.Children[3];
  8             var child4 = this.Viewport3D.Children[4];
  9             var child5 = this.Viewport3D.Children[5];
 10 
 11 
 12             this.Viewport3D.Children.RemoveAt(0);
 13             this.Viewport3D.Children.Insert(5, current);
 14 
 15             var translate = (current.Transform as Transform3DGroup).Children[1
                                                        as TranslateTransform3D;
 16 
 17             //对每个Viewport2DVisual3D元素应用平移动画
 18             AnimationVisualElement((current as Viewport2DVisual3D).Visual 
                                                   as FrameworkElement, .3);
 19             AnimationVisualElement(translate, true-5.01.5-20.0);
 20 
 21             translate = (child1.Transform as Transform3DGroup).Children[1
                                                     as TranslateTransform3D;
 22             AnimationVisualElement(translate, true, .0, .0, .0);
 23 
 24             translate = (child2.Transform as Transform3DGroup).Children[1
                                                       as TranslateTransform3D;
 25             AnimationVisualElement(translate, true-1.01.0-4.0);
 26 
 27             translate = (child3.Transform as Transform3DGroup).Children[1
                                                        as TranslateTransform3D;
 28             AnimationVisualElement(translate, true-2.01.5-8.0);
 29 
 30             translate = (child4.Transform as Transform3DGroup).Children[1
                                                        as TranslateTransform3D;
 31             AnimationVisualElement(translate, true-3.01.5-12.0);
 32 
 33             translate = (child5.Transform as Transform3DGroup).Children[1
                                                        as TranslateTransform3D;
 34             AnimationVisualElement(translate, true-4.01.5-16.0);
 35 
 36         }
 37 
 38         public void MoveCurrentToPrevious()
 39         {
 40             //向后移动,取Viewport3D的最后一个Viewport2DVisual3D当前Viewport2DVisual3D
 41             var current = this.Viewport3D.Children[5];
 42             var child1 = this.Viewport3D.Children[0];
 43             var child2 = this.Viewport3D.Children[1];
 44             var child3 = this.Viewport3D.Children[2];
 45             var child4 = this.Viewport3D.Children[3];
 46             var child5 = this.Viewport3D.Children[4];
 47 
 48             this.Viewport3D.Children.RemoveAt(5);
 49             this.Viewport3D.Children.Insert(0, current);
 50 
 51             var translate = (current.Transform as Transform3DGroup).Children[1
                                                            as TranslateTransform3D;
 52 
 53             AnimationVisualElement(translate, false0.00.00.0);
 55 
 56             translate = (child1.Transform as Transform3DGroup).Children[1
                                                       as TranslateTransform3D;
 57             AnimationVisualElement(translate, false-1.01.0-4.0);
 58 
 59             translate = (child2.Transform as Transform3DGroup).Children[1
                                                       as TranslateTransform3D;
 60             AnimationVisualElement(translate, false-2.01.5-8.0);
 61 
 62             translate = (child3.Transform as Transform3DGroup).Children[1
                                                         as TranslateTransform3D;
 63             AnimationVisualElement(translate, false-3.01.5-12.0);
 64 
 65             translate = (child4.Transform as Transform3DGroup).Children[1
                                                        as TranslateTransform3D;
 66             AnimationVisualElement(translate, false-4.01.5-16.0);
 67 
 68             translate = (child5.Transform as Transform3DGroup).Children[1
                                                        as TranslateTransform3D;
 69             AnimationVisualElement(translate, false-5.01.5-20.0);
 70         }
 71         private void AnimationVisualElement(FrameworkElement element, double duration)
 72         {
 73             if (element == null)
 74                 return;
 75             //对Visual元素的Visibility应用动画
 76             ObjectAnimationUsingKeyFrames objectAnimation = new ObjectAnimationUsingKeyFrames();
 77             objectAnimation.KeyFrames.Add(
                  new DiscreteObjectKeyFrame(Visibility.Collapsed, KeyTime.FromPercent(.0)));
 78             objectAnimation.KeyFrames.Add(
                  new DiscreteObjectKeyFrame(Visibility.Visible, KeyTime.FromPercent(1)));
 79             objectAnimation.Duration = TimeSpan.FromSeconds(duration);
 80             objectAnimation.FillBehavior = FillBehavior.Stop;
 81             element.BeginAnimation(FrameworkElement.VisibilityProperty, objectAnimation);
 82 
 83         }
 84         private void AnimationVisualElement(TranslateTransform3D translate, bool forward, 
                                                  double targetX, double targetY, double targetZ)
 85         {
 86             Duration duration = new Duration(TimeSpan.FromSeconds(.4));
 87             //对TranslateTransform3D的X偏移量应用动画
 88             DoubleAnimation animationX = new DoubleAnimation();
 89             animationX.To = targetX;
 90             animationX.Duration = duration;
 91             animationX.AccelerationRatio = forward ? 0 : 1;
 92             animationX.DecelerationRatio = forward ? 1 : 0;
 93             translate.BeginAnimation(TranslateTransform3D.OffsetXProperty, animationX);
 94             //对TranslateTransform3D的Y偏移量应用动画
 95             DoubleAnimation animationY = new DoubleAnimation();
 96             animationX.To = targetY;
 97             animationX.AccelerationRatio = forward ? 0.7 : 0.3;
 98             animationX.DecelerationRatio = forward ? 0.3 : 0.7;
 99             animationX.Duration = duration;
100             translate.BeginAnimation(TranslateTransform3D.OffsetYProperty, animationX);
101             //对TranslateTransform3D的Z偏移量应用动画
102             DoubleAnimation animationZ = new DoubleAnimation();
103             animationZ.To = targetZ;
104             animationZ.AccelerationRatio = forward ? 0.3 : 0.7;
105             animationZ.DecelerationRatio = forward ? 0.7 : 0.3;
106             animationZ.Duration = duration;
107             translate.BeginAnimation(TranslateTransform3D.OffsetZProperty, animationZ);
108         }

     在以上代码中主要实现了对ViewPort3D的6个子Viewport2DVisual3D分别应用TranslateTransform3D的平移动画,TranslateTransform3D具有三个跟位置有关的属性,分别表示X轴偏移量OffsetX,Y轴偏移量OffsetY,以及Z轴偏移量OffsetZ

    由于OffsetX,OffsetY,OffsetY在TranslateTransform3D中被定义为Double类型的依赖项属性,因此可以使用DoubleAnimation对属性的目标值定义动画效果,最后通过TranslateTransform3D的BeginAnimation方法分别对OffsetX,OffsetY,OffsetY属性应用动画

    最后定义快捷键事件,按下Ctrl+Down组合键,图片向前滑动,按下Ctrl+Up组合键,图片向后滑动

定义快捷键 
 1  private void Window_KeyDown(object sender, KeyEventArgs e)
 2         {
 3             if (e.KeyStates == Keyboard.GetKeyStates(Key.Down) && 
 4                         Keyboard.Modifiers == ModifierKeys.Control)
 5             {
 6                 //向前移动Visual元素
 7                 this.MoveCurrentToNext();
 8             }
 9             else if (e.KeyStates == Keyboard.GetKeyStates(Key.Up) && 
10                        Keyboard.Modifiers == ModifierKeys.Control)
11             {
12                 //向后移动Visual元素
13                 this.MoveCurrentToPrevious();
14             }
15             else if (e.KeyStates == Keyboard.GetKeyStates(Key.Escape))
16             {
17                 //注销
18                 Application.Current.Shutdown();
19             }
20         }

    注:在本示例中连续使用了6个Viewport2DVisual3D三维元素,并且在每个Viewport2DVisual3D元素的Visual上宿主一个二维的Image控件,对于本示例,为优化性能,应尽可能的减少Viewport2DVisual3D的数目,在这里一个好的方法是使用三维元素ModelVisual3D来代替Viewport2DVisual3D,将六幅图片分别定义成Material,再将Material应用到六个对应的GeometryModel3D三维模型中,最后使用Model3DGroup将六个GeometryModel3D三维模型打包作为ModelVisual3D的Content属性值,因此只需要一个ModelVisual3D就可实现相同的功能并能优化了性能

 

posted @ 2010-09-01 15:09  顾点点  阅读(5164)  评论(7编辑  收藏  举报