我有一个绑定到我无法控制的集合类的TreeView。在这个类中是一个对象集合,每个对象都有自己的项集合。此层次结构固定为3深。 TreeView的子项包含在ObservableCollection中,并相应地在TreeView中更新。每个对象内部的集合都是不可观察的,因此每次向其中一个子节点添加对象时,我都必须手动将数据重新绑定到TreeView。这会导致所有已展开的子项重置为未展开状态。我正在尝试缓存已扩展的对象,以便在重新绑定后重新展开它们。孩子们按照我的预期工作,但是当我尝试扩展TreeView的孙子时,我得到一个空对象。
要获取TreeViewItem,我使用ItemsControl的ItemContainerGenerator属性:
TreeViewItem cfItem = treeView.ItemContainerGenerator
.ContainerFromItem(obj) as TreeViewItem;
cfItem.IsExpanded = true;
第二级集合都具有对其父对象的引用。因为我有很多这样的对象,所以它们被循环并且每个都使用它的父对象来查找它的父对象的TreeViewItem。它们被添加到集合中的顺序保证(我认为)子节点将始终在父节点之后处理。因此,我得到了这条丑陋的代码:
qualItem = (
(TreeViewItem)treeView.ItemContainerGenerator
.ContainerFromItem(
((Child)obj).ParentObject
)
)
.ItemContainerGenerator.ContainerFromItem(obj) as TreeViewItem;
当该行尝试从项目obj获取容器时,该行总是失败。它成功获取父TreeViewItem,但在尝试获取Child的TreeViewItem容器时,我总是收到null。文档说明ContainerFromItem()返回
“一个System.Windows.UIElement 对应于给定的项目。返回 如果该项不属于null,则返回null 项目集合,或者如果是 System.Windows.UIElement还没有 为它生成。“
我知道父级的项目集合中存在二级子级。我在VS 2010中检查了调试器,所有项目都在那里。我花了很多时间在谷歌搜索答案,并遇到一个人说,容器项是在后台工作线程上创建的,并且在尝试获取子项容器时可能不会生成。我试着等待ItemContainerGenerator的Status属性等于GeneratorStatus.ContainersGenerated,但我仍然得到相同的结果。我需要以某种方式为我的二级孩子获取TreeViewItem容器,这样他们就可以像第一级孩子一样重新扩展。
答案 0 :(得分:0)
“与给定项目对应的System.Windows.UIElement。如果项目不属于项目集合,则返回null;如果尚未为其生成System.Windows.UIElement,则返回 “
看起来因为Virtualization
,您寻找的UIElement
在寻找时并不存在。如果集合不是太大,请尝试关闭Virtualization
。
答案 1 :(得分:0)
解决方案是在数据和TreeView之间添加另一层抽象。顶级集合是一个ObservableCollection,它包含几个ViewModel,它们实现了INotifyPropertyChanged,并且还有ObservableCollections元素位于它下面的树中。该系统允许WPF更容易地绑定和跟踪正在添加和删除的元素。
我的主要信息来源是这篇文章: