问题背景
这个问题是在最近写WPF程序的时候遇到的。具体来说,假如我在前端定义了一个TreeView,并将其命名为MyTreeView。我该如何通过这个MyTreeView得到其某个元素的容器(对于TreeView来说就是TreeViewItem)。不同于Winform程序,我们可以直接通过MyTreeView.Nodes
这种方式得到一个TreeNodeCollection。在WPF中,由于数据与容器分离的思想,我们好像无法通过一个属性得到所有的TreeViewItem集合。
如何获取到集合数据
在WPF中,我们可以通过两种方式去获取到其对应的集合数据。分别是Items和ItemsSource(对于两种方法的区别可以去查一下文档或者问一下AI,这两种方法不是完全相等的)。
集合数据项到容器的转换
上面已经介绍了,如何获取到集合控件所对应的集合数据项,如何通过这个集合数据项映射为一个对应的容器,可以通过下面的方法。
点击查看代码
private void GetTreeNodesStatus(ItemsControl control)
{TreeView treeView = new Tree// TreeView不为空if (control != null){// 遍历所有节点,Items中对应的是绑定的数据源中的每一项foreach (object item in control.Items){// 根据数据源中的每一项 得到其在TreeView中对应的每一个TreeViewItemsTreeViewItem treeItem = control.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;// 如果treeItem不为空且有子项if (treeItem != null && treeItem.HasItems){// 获取插件NodeModuleNode moduleNode = treeItem.DataContext as ModuleNode;// 则需要展开m_NodesStatusDic[moduleNode.Name] = treeItem.IsExpanded;// 递归,如果子项还有子项递归设置为展开状态GetTreeNodesStatus(treeItem as ItemsControl);}}}}
control.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
就实现了从数据项映射为对应控件容器的操作。该方法会从对应的容器中通过模式匹配的方式,找到对应当前数据项的容器并返回。