如果将ListView ItemsContainer设置为VirtualizationStackPanel,则无法正确获取所选项目

我将’VirtualizingStackPanel.IsVirtualizing’设置为true,将’VirtualizingStackPanel.VirtualizationMode’设置为’Recycling’,因为我的ListView中的项目太多了。 ListView的SelectionMode是Extended,ListViewItem的’IsSelected’属性绑定到我的模型的’IsSelected’属性,绑定模式是双向的。

当我想使用Ctrl + A选择所有项目时,它只选择部分项目,所以我使用KeyBinding来编写如下所示的全选方法:

 

SelectAll方法将循环ItemsSource集合并将项目的每个IsSelected属性设置为true。 但它也会导致意想不到的事情。 选中所有项目后,我将滚动条滚动到底部,它会将更多项目加载到ListView,我单击一个项目,预期所有其他项目都被取消选中,只选择此项目。 但是,似乎没有取消选择其他项目。

有人可以帮忙吗?

选择器的这种行为是可以预期的,因为它只能在加载的UI元素上运行。 由于启用虚拟化,您只加载了包含在可见区域中的元素。 因此,Selector并不“了解”其他人。

为了解决这个问题,你必须这样做,选择器“知道”以前选择的项目。 换句话说,您必须禁止卸载所选的任何UI元素。

首先,使用二十一点和妓女创建自己的虚拟化面板:

 public class MyVirtualizingStackPanel : VirtualizingStackPanel { protected override void OnCleanUpVirtualizedItem(CleanUpVirtualizedItemEventArgs e) { var item = e.UIElement as ListBoxItem; if (item != null && item.IsSelected) { e.Cancel = true; e.Handled = true; return; } var item2 = e.UIElement as TreeViewItem; if (item2 != null && item2.IsSelected) { e.Cancel = true; e.Handled = true; return; } base.OnCleanUpVirtualizedItem(e); } } 

接下来,替换ListBox,ListView,TreeView或其他提供选择器的用户控件中的默认面板。 例如,通过样式:

        

…或者,直接在您的选择器中:

      

请享用!

我希望我的回答对你有帮助。