30天学通C#项目案例开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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文件中,本章的配套源程序提供了详尽的介绍,请参见光盘中的源代码。