虚拟化的集合项容器一致性

本文关键字:一致性 集合 虚拟化 | 更新日期: 2023-09-27 18:29:33

我正在实现一个自定义MultiSelectionTreeView。此控件从ItemsControl继承,MultiSelectionTreeViewItemTreeViewItem继承。由于数据集很大,我想绑定到这个控件,所以我使用VirtualizationStackPanel作为它的主机。

我将TreeViewItems IsSelected属性绑定到ViewModelClass IsSelected属性。当我在树中向下滚动时,所选项目会离开视口,并且IsSelected属性设置为false(由于虚拟化,MultiSelectionTreeViewItems与树断开连接)。当我向后滚动时,会创建一个新的项目容器(MultiSelectionTreeViewItem),并且根据ViewModel将该容器的IsSelected属性设置为true。

现在,我无法决定"选定"事件的发生是因为容器项目从视口传出/返回视口,还是因为模型或视图模型层发生了更改。

更糟糕的是,我无法设置断开连接项目的IsSelected属性。例如,在向下滚动的情况下,对更多项目使用Shift选择。

我无法访问控件实现中的视图模型类。

知道吗?

虚拟化的集合项容器一致性

如果创建一个自定义的虚拟化实现,就可以解决这个问题。碰巧,我在网上找到了一个PDF格式的书的链接。这本书有一个伟大的章节关于虚拟化(第8章)。。。WPF控制开发释放。

尽管我已经使用这些信息实现了自己的虚拟化面板,但我不得不说这相当复杂。然而,如果您确实实现了自己的系统,您可以向视图模型对象添加另一个属性:

public bool IsRealized { get; set; }

"已实现"项是指实际可见的项,而不是仅驻留在内存中的"虚拟化"项。因此,使用此属性,您可以调整IsSelected属性,使其仅在IsRealized属性为true:时发生反应

public bool IsSelected
{ 
    get { return isSelected; }
    set { if (IsRealized) { isSelected = value; NotifyPropertyChanged("IsSelected"); }
}

然后,在自定义虚拟化面板中,您可以在每次实现或虚拟化项目时设置IsRealized属性。。。不过我必须警告你。。。这将是一项艰巨的工作。