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

2.4.4 遍历窗体可视化树

在WPF中,窗体上的所有UI元素都属于Windows逻辑树。通过可视化树,开发人员可以获取对于正确的Item的引用,并且直接改变其属性。再次重申,3D效果实际上是DataTemplate的一部分,其被作为一个ItemsControl中的单个Item。当将显示风格设置为3D模式时,将会触发AddNewFriendControl的SizeChanged事件,因此通过这个事件来更新位于3D DataTemplate中的内容,代码如下所示。

代码位置:见光盘中本章源代码的MainInterfaceWindow.xaml.cs文件。

01        void AddNewFriendControl_SizeChanged(object sender,SizeChangedEventArgse)
02        {
03           addfriendsControl3D = sender as AddNewFriendControl; //获取对象引用
04           addfriendsControl3D.ReInitialise();    //重新初始化最后一次的联系人内容
05           //获取ViewAllUsersControl有些技巧
06           //需要在DataTemplate中查找,意味着需要遍历视觉树
07           DependencyObject item = null;
08           //因为DataItem中只有一个Item,作为一个技巧方法来应用自定义的3D模板
09           foreach (object dataitem in items3d.Items)
10           {
11              //获取ItemsControl中的UIElement
12              item = items3d.ItemContainerGenerator.
13                 ContainerFromItem(dataitem);
14              int count = VisualTreeHelper.GetChildrenCount(item);
15              for (int i = 0; i < count; i++)
16              {
17                 DependencyObject itemFetched =
18                    VisualTreeHelper.GetChild(item, i);
19                 //查找Grid,找出哪一个为其相关的宿主
20                 //ViewAllUsersControl的ContentPresenter
21                 if (itemFetched is Grid)
22                 {
23                    //查找backContent中的ViewAllUsersControl,
24                    //设置其高度并重新绑定数据
25                    ContentPresenter cp = (itemFetched as Grid).
26                       FindName("backContent") as ContentPresenter;
27                    DataTemplate myDataTemplate = cp.ContentTemplate;
28                    ViewAllUsersControl viewUsers = (ViewAllUsersControl)
29                       myDataTemplate.FindName("viewFriendsControl3d", cp);
30                    viewUsers.Height=(sender as AddNewFriendControl).Height;
31                    viewUsers.DataBind();
32                    return;
33                 }
34              }
35           }
36        }

● 第03~04行代码中,第03行代码通过类型转换将sender参数强制转换为AddNew FriendControl,然后调用ReInitialise方法重新初始化最后一次更新的联系人内容。

● 第09~35行代码遍历ItemsControl中的Item项。

● 第12~13行代码获取ItemsControl中的UIElement元素。

● 第14行获取第12~13行代码中返回的UIElement中的子元素的个数。这里使用了VisualTreeHelper辅助类的函数来获取子元素的个数。

● 第15~18行代码调用VisualTreeHelper的GetChild方法获取指定位置的Item。

● 第21~32行代码将查找Grid中的DataTemplate,获取其中的ViewAllUsersControl控件的引用,设置其高度并重新绑定数据。

在可视化树中查找ViewAllUsersControl的示意图如图2.12所示。

图2.12 可视化树查找示意图

可以看到,代码首先查Grid,根据Grid的ContentPresenter找到其DataTemplate,在DataTemplate模板中找到ViewAllUsersControl。