虚拟化的集合项容器一致性
本文关键字:一致性 集合 虚拟化 | 更新日期: 2023-09-27 18:29:33
我正在实现一个自定义MultiSelectionTreeView
。此控件从ItemsControl
继承,MultiSelectionTreeViewItem
从TreeViewItem
继承。由于数据集很大,我想绑定到这个控件,所以我使用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
属性。。。不过我必须警告你。。。这将是一项艰巨的工作。