1

我有一个绑定到我无法控制的集合类的 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。如果项目不属于项目集合,或者尚未为其生成 System.Windows.UIElement,则返回 null。”

我知道第二级子级存在于父级的项目集合中。我在 VS 2010 中检查了调试器,所有项目都在那里。我花了很多时间在谷歌上寻找答案,遇到有人说容器项目是在后台工作线程上创建的,并且在尝试获取子项目容器时可能不会生成。我尝试等待 ItemContainerGenerator 的 Status 属性等于 GeneratorStatus.ContainersGenerated,但我仍然得到相同的结果。我需要以某种方式为我的第二级孩子获取 TreeViewItem 容器,以便可以像第一级孩子一样重新扩展它们。

4

2 回答 2

0

“与给定项目相对应的 System.Windows.UIElement。如果项目不属于项目集合,或者尚未为其生成 System.Windows.UIElement ,则返回 null 。”

看起来因为VirtualizationUIElement当您寻找它时,您寻找的不存在。如果集合不是太大,请尝试Virtualization关闭。

于 2010-06-28T19:11:32.633 回答
0

解决方案是在数据和 TreeView 之间添加另一层抽象。顶级集合是一个 ObservableCollection,它包含多个 ViewModel,它们实现了 INotifyPropertyChanged,并且还具有位于其下方的树中的 ObservableCollections 元素。该系统允许 WPF 更轻松地绑定和跟踪正在添加和删除的元素。

我的主要信息来源是这篇文章:

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

于 2010-07-28T13:25:47.960 回答