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。