WPF案例(-)模拟Windows7 Win+Tab切换
原文: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 { get; set; }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代码

2 <Viewport3D.Camera>
3 <PerspectiveCamera Position="0,0,8" />
4 </Viewport3D.Camera>
5 <Viewport2DVisual3D x:Name="viewport2DVisual3D0" Geometry="{StaticResource geometry}"
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"
15 </Transform3DGroup>
16 </Viewport2DVisual3D.Transform>
17 <Viewport2DVisual3D.Visual>
18 <Image Source="Images\051027nature01.jpg" Stretch="Fill"
19 </Viewport2DVisual3D.Visual>
20 </Viewport2DVisual3D>
21 <Viewport2DVisual3D x:Name="viewport2DVisual3D1" Geometry="{StaticResource geometry}"
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"
31 </Transform3DGroup>
32 </Viewport2DVisual3D.Transform>
33 <Viewport2DVisual3D.Visual>
34 <Image Source="Images\051027nature02.jpg" Stretch="Fill"
35 </Viewport2DVisual3D.Visual>
36 </Viewport2DVisual3D>
37 <Viewport2DVisual3D x:Name="viewport2DVisual3D2" Geometry="{StaticResource geometry}"
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"
47 </Transform3DGroup>
48 </Viewport2DVisual3D.Transform>
49 <Viewport2DVisual3D.Visual>
50 <Image Source="Images\11550549.jpg" Stretch="Fill"
51 </Viewport2DVisual3D.Visual>
52 </Viewport2DVisual3D>
53 <Viewport2DVisual3D x:Name="viewport2DVisual3D3" Geometry="{StaticResource geometry}"
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"
63 </Transform3DGroup>
64 </Viewport2DVisual3D.Transform>
65 <Viewport2DVisual3D.Visual>
66 <Image Source="Images\11550556.jpg" Stretch="Fill"
67 </Viewport2DVisual3D.Visual>
68 </Viewport2DVisual3D>
69 <Viewport2DVisual3D x:Name="viewport2DVisual3D4" Geometry="{StaticResource geometry}"
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"
79 </Transform3DGroup>
80 </Viewport2DVisual3D.Transform>
81 <Viewport2DVisual3D.Visual>
82 <Image Source="Images\11550560.jpg" Stretch="Fill"
83 </Viewport2DVisual3D.Visual>
84 </Viewport2DVisual3D>
85 <Viewport2DVisual3D x:Name="viewport2DVisual3D5" Geometry="{StaticResource geometry}"
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"
95 </Transform3DGroup>
96 </Viewport2DVisual3D.Transform>
97 <Viewport2DVisual3D.Visual>
98 <Image Source="Images\051123Webshots05.jpg" Stretch="Fill"
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切换特效

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]
16
17 //对每个Viewport2DVisual3D元素应用平移动画
18 AnimationVisualElement((current as Viewport2DVisual3D).Visual
19 AnimationVisualElement(translate, true, -5.0, 1.5, -20.0);
20
21 translate = (child1.Transform as Transform3DGroup).Children[1]
22 AnimationVisualElement(translate, true, .0, .0, .0);
23
24 translate = (child2.Transform as Transform3DGroup).Children[1]
25 AnimationVisualElement(translate, true, -1.0, 1.0, -4.0);
26
27 translate = (child3.Transform as Transform3DGroup).Children[1]
28 AnimationVisualElement(translate, true, -2.0, 1.5, -8.0);
29
30 translate = (child4.Transform as Transform3DGroup).Children[1]
31 AnimationVisualElement(translate, true, -3.0, 1.5, -12.0);
32
33 translate = (child5.Transform as Transform3DGroup).Children[1]
34 AnimationVisualElement(translate, true, -4.0, 1.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]
52
53 AnimationVisualElement(translate, false, 0.0, 0.0, 0.0);
55
56 translate = (child1.Transform as Transform3DGroup).Children[1]
57 AnimationVisualElement(translate, false, -1.0, 1.0, -4.0);
58
59 translate = (child2.Transform as Transform3DGroup).Children[1]
60 AnimationVisualElement(translate, false, -2.0, 1.5, -8.0);
61
62 translate = (child3.Transform as Transform3DGroup).Children[1]
63 AnimationVisualElement(translate, false, -3.0, 1.5, -12.0);
64
65 translate = (child4.Transform as Transform3DGroup).Children[1]
66 AnimationVisualElement(translate, false, -4.0, 1.5, -16.0);
67
68 translate = (child5.Transform as Transform3DGroup).Children[1]
69 AnimationVisualElement(translate, false, -5.0, 1.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(
78 objectAnimation.KeyFrames.Add(
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,
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组合键,图片向后滑动

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就可实现相同的功能并能优化了性能
WPF案例(-)模拟Windows7 Win+Tab切换的更多相关文章
- WPF案例 (四) 模拟Windows7桌面任务栏
原文:WPF案例 (四) 模拟Windows7桌面任务栏 这个程序模彷了Windows7的桌面任务栏,当在桌面上双击某个快捷方式时,将打开一个新的子界面,并且在任务栏里创建一个链接到此界面的任务栏图标 ...
- WPF案例 (三) 模拟QQ“快速换装"界面
原文:WPF案例 (三) 模拟QQ"快速换装"界面 这个小程序使用Wpf模拟QQ快速换装页面的动画特效,通过使用组合快捷键Ctrl+Left或Ctrl+Right,可实现Image ...
- WPF案例 (六) 动态切换UI布局
原文:WPF案例 (六) 动态切换UI布局 这个Wpf示例对同一个界面支持以ListView或者CardView的布局方式呈现界面,使用控件ItemsControl绑定数据源,使用DataTempla ...
- WPF案例(二)模拟Apple OS 界面前后180度反转
原文:WPF案例(二)模拟Apple OS 界面前后180度反转 我们在设计应用程序界面的时候,为了充分利用界面空间,住住需要灵活的界面布局方式,比如可以在界面正面空间上定义一个Chart,背面空间上 ...
- Android Studio精彩案例(二)《仿微信动态点击底部tab切换Fragment》
转载本专栏文章,请注明出处,尊重原创 .文章博客地址:道龙的博客 现在很多的App要么顶部带有tab,要么就底部带有tab.用户通过点击tab从而切换不同的页面(大部分情况时去切换fragment). ...
- Angular——tab切换案例
基本介绍 angular框架下的tab切换,相比较于之前的纯js写的代码,有一个很大的特点就是以数据为驱动,基本上不用搜索dom元素就可以实现效果 基本使用 (1)导航部分使用的是的状态使用的是ng- ...
- tab切换案例
做个简单的tab切换效果,分别于jquery和js操作 (1)jQuery操作 先看下效果: <!DOCTYPE html> <html lang="en"> ...
- 案例(拖拽对话框、高清放大镜、自制滚动条、元素的隐藏方式、表格隔行变色、tab切换效果、字符串拼接、刷新评论)
一.拖拽对话框 <style> .of{ width: 500px; } #link,#close{ text-decoration: none; margin: 0 10px; font ...
- 基于zepto的H5/移动端tab切换触摸拖动加载更多数据
以前实现移动端的滑动加载更多实现的方法是当滚动条快到页面底部时就自动加载更多的数据,在这方面很多人都用的是"西门的后花园"写的一个叫dropload的插件,这个插件用起来也很好,很 ...
随机推荐
- js操作styleSheets
document.styleSheets这个接口可以获取网页上引入的link样式表和style样式表.比如 最后的输出结果如下. 换下代码看看我们具体的styleSheets具体输出什么 这些都是次要 ...
- 一道c++小编程题,
题目: 编写一个小程序,从标准输入读入一系列string对象,寻找连续重复出现的单词,程序应该找出满足以下条件的单词的输入位置:该单词的后面紧跟着再次出现自己本身,跟 踪重复次数量多的单词及其重复次数 ...
- Hadoop 2.x从零基础到挑战百万年薪第一季
鉴于目前大数据Hadoop 2.x被企业广泛使用,在实际的企业项目中需要更加深入的灵活运用,并且Hadoop 2.x是大数据平台处理 的框架的基石,尤其在海量数据的存储HDFS.分布式资源管理和任务调 ...
- 通过IP或socket获取对方的MAC地址
1.通过已经连接的socket文件获取: int getpeermac( int sockfd, char *buf ) { int ret =0; struct arpreq arpreq; str ...
- SRM 583 Div II Level One:SwappingDigits
题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12609 #include <iostream> # ...
- Java中的throw和throws的差别
Java中的throw和throws的差别 1.throwkeyword用于方法体内部.而throwskeyword用于方法体部的方法声明部分: 2.throw用来抛出一个Throwable类型的异常 ...
- 用log(N)的解法实现数值的整数次方
// // main.m // c++test // // Created by andyyang on 6/3/13. // Copyright (c) 2013 andyyang. All rig ...
- gulp工作流
小屁活动使用 gulp+less gulpfile.js var gulp = require('gulp'), cssmin = require('gulp-minify-css'), less = ...
- 扩展SpringMVC以支持绑定JSON格式的请求参数
此方案是把请求参数(JSON字符串)绑定到java对象,,@RequestBody是绑定内容体到java对象的. 问题描述: <span style="font-size: x-sma ...
- Mysql 5.1升级为mysql 5.6遇到的问题及解决方式
yum是不可行的.因为yum源没更新,我已经使用了163网易的源,但是还是不行.最新版仍然不是5.6.没办法,mysql分区是5.5之后的功能,要使用分区功能,就必须升级.. 去官网下载地址:http ...