2.4.3 3D动画功能的实现
当用户单击“选项”按钮,在显示风格中设置为3D翻页效果时,主窗口的“添加联系人”按钮和“查看所有联系人”按钮将被禁用。在“添加联系人”控件和“查看所有联系人”控件的底部会增加一个黄色的按钮条,允许用户单击来进行3D翻页转场,如图2.11所示。
图2.11 3D翻页风格底部新增的黄色按钮条
“选项”按钮的单击事件处理代码为3D翻页进行了一些初始化的操作,代码如下所示。
代码位置:见光盘中本章源代码的MainInterfaceWindow.xaml.cs文件。
01 private void btnOptions_Click(object sender, RoutedEventArgs e) 02 { 03 switch (currentDisplayOption) 04 { 05 case CurrentDisplayOption.AddIsShown: 06 topleft = //根据当前的显示状态设置控件的初始位置 07 addFriendsControl.PointToScreen(new Point(0, 0)); 08 break; 09 case CurrentDisplayOption.ViewIsShown: 10 topleft = //如果当前查看联系人为显示状态,则将其定位到左上角 11 viewAllUsersControl.PointToScreen(new Point(0, 0)); 12 break; 13 } 14 OptionsWindow optionsWin = new OptionsWindow();//选项窗口 15 optionsWin.Owner = this; 16 optionsWin.CurrentDisplayStyle = currentDisplayStyle; //设置选项的当前显示风格 17 optionsWin.WindowStartupLocation = 18 WindowStartupLocation.CenterScreen;//窗口位置 19 optionsWin.ShowDialog(); //显示“选项”按钮 20 //获取定义在应用程序属性中的显示风格 21 DisplayStyle newDisplayStle = (DisplayStyle)Application. 22 Current.Properties["SelectedDisplayStyle"]; 23 bool showingAddControl = false; //控件显示布尔值 24 if (newDisplayStle != currentDisplayStyle) 25 { //判断新的风格与当前风格是否一致 26 if (newDisplayStle.Equals(DisplayStyle.ThreeDimension)) 27 { //如果新的风格为三维风格 28 Create3Area(); //用于创建三维动画区域 29 btnViewAllFriends.IsEnabled = false; //禁用“查看”按钮 30 btnAddFriend.IsEnabled = false; //禁用“添加”按钮 31 } 32 else 33 { //如果是动画风格 34 CreateAlphaGrowArea(false); //初始化动画方法 35 switch (currentDisplayOption) 36 { //根据当前的显示状态设置控件的可见性与按钮的可用性 37 case CurrentDisplayOption.AddIsShown: 38 viewAllUsersControl.Visibility = Visibility.Visible; 39 showingAddControl = true; 40 break; 41 case CurrentDisplayOption.ViewIsShown: 42 showingAddControl = false; 43 viewAllUsersControl.Visibility = Visibility.Visible; 44 break; 45 } 46 //根据是否显示设置按钮的启用或禁用 47 btnViewAllFriends.IsEnabled = showingAddControl; 48 btnAddFriend.IsEnabled = !showingAddControl; 49 } 50 } 51 }
● 第03~12行代码将根据当前的显示选项重新对控件进行定位。
● 第14~19行代码打开选项窗口供用户进行设置,显示风格设置将保存到全局应用程序属性中。
● 第21~22行代码将获取全局应用程序属性的值。
● 第24~31行代码判断用户选择的风格是否是三维风格,如果是,则调用Create3Area()方法初始化三维动画区域。然后设置按钮的状态。
● 第32~45行代码在用户选择的是缩放动画风格时,根据当前显示选项设置控件和按钮的状态。
● 第47~48行代码则根据当前显示的控件来设置导航按钮的显示与隐藏。
Create3Area()方法将实现三维的初始化操作,它将创建一个ItemsControl控件,为其ItemTemplate赋一个定义在资源中的数据模板,然后添加一个单独的项,最后将ItemsControl控件添加到容器Grid中,代码如下所示。
代码位置:见光盘中本章源代码的MainInterfaceWindow.xaml.cs文件
01 private void Create3Area() //创建三维动画区域 02 { 03 currentDisplayStyle = DisplayStyle.ThreeDimension; //设置当前显示风格 04 if(mainGrid.Children.Contains(gridHolder))//将控件移动到Grid中 05 mainGrid.Children.Remove(gridHolder); 06 if (!GridOuter.Children.Contains(gridHolder)) 07 GridOuter.Children.Add(gridHolder); 08 gridHolder.Visibility = Visibility.Collapsed; //折叠控件 09 //取消关联委拖,在3D模式时将不使用动画 10 if (Grow_Hide_AddUserControlStoryBoard != null) 11 Grow_Hide_AddUserControlStoryBoard.Completed -= //移除故事板事件 12 new EventHandler(Grow_Hide_AddUserControl_Completed); 13 if (Shrink_Show_AddUserControlStoryBoard != null) 14 Shrink_Show_AddUserControlStoryBoard.Completed -= //移除故事板事件 15 new EventHandler(Shrink_Show_AddUserControl_Completed); 16 //现在创建3D动画区域 17 items3d = new ItemsControl(); //实例化一个ItemsControl 18 //设置控件的对齐依赖属性 19 items3d.SetValue(Grid.HorizontalAlignmentProperty, Horizontal Alignment.Center); 20 items3d.SetValue(Grid.VerticalAlignmentProperty, Vertical Alignment.Center); 21 //设置控件的ItemTemplate模板为资源flipItemTemplate模板 22 items3d.ItemTemplate=this.TryFindResource("flipItemTemplate") as DataTemplate; 23 items3d.Items.Add("dont care"); //随便添加一项 24 mainGrid.Children.Clear(); //清除容器Grid 25 mainGrid.Children.Add(items3d); // 添加ItemsControl控件 26 }
● 第04行代码设置当前的显示风格为三维显示风格。
● 第06~10行代码将移除容器中的控件,将gridHolder中的控件添加到GridOuter中作为子元素。然后隐藏gridHolder的显示。
● 第12~19行代码判断故事板是否被实例化并移除为其关联的Completed事件。
● 第20~26行代码是实现3D最重要的代码,它创建了一个ItemsControl控件,为其指定一个定义在资源中的数据模板,然后将ItemsControl控件添加到mainGrid中。
3D动画的核心位于XAML文件中的DataTemplate数据模板中,下面分析一下该数据模板的实现。关于3D有一些事情需要理解,如下所示。
● 当前显示的控件实际上是DataTemplate的一部分,也就是说当前显示的控件实际上是一个数据模板。
● DataTemplate实际上被应用到一个ItemsControl控件,在前面代码中的Items3d。
● ItemsControl每次只能包含一个Item,内容是什么并不重要。它只需要一个假的入口在ItemsControl内部,以便为其赋予具有三维效果的DataTemplate。实际上在代码中, items3d.Items.Add("dont care")是不会显示出来的,因为实际的工作都在DataTemplate中实现了。
经过上面的讨论,DataTemplate是如何达到3D效果的呢,DataTemplate是最主要的行为发生地,基本思路是放一个Viewport3D,为3D视觉内容提供一个渲染表面。Viewport3D放了一个Viewport3D.Camera和初始的GeometryModel3D,这是一个3D模型,由MeshGeometry3D和一个Material组成。在WPF中3D也公开为一个GeometryModel3D.BackMaterial属性,在主窗口的XAML文件中,本章的配套源程序提供了详尽的介绍,请参见光盘中的源代码。