如何在UWP中清除虚拟化ListView上的选择?

如何在UWP中清除虚拟化ListView上的选择?,listview,win-universal-app,Listview,Win Universal App,我有点怀疑。我有一个很大的列表容器,可能有数千个项目。当我进行虚拟化(这几乎是对性能的要求)时,只要我尝试更新选择,就会出现此异常: Failed to update selection | [Exception] System.Exception: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) at System.Runtime.InteropServices.WindowsRuntime

我有点怀疑。我有一个很大的列表容器,可能有数千个项目。当我进行虚拟化(这几乎是对性能的要求)时,只要我尝试更新选择,就会出现此异常:

Failed to update selection | [Exception] System.Exception: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at System.Runtime.InteropServices.WindowsRuntime.IVector`1.RemoveAt(UInt32 index)
   at System.Runtime.InteropServices.WindowsRuntime.VectorToListAdapter.RemoveAtHelper[T](IVector`1 _this, UInt32 index)
   at System.Runtime.InteropServices.WindowsRuntime.VectorToListAdapter.RemoveAt[T](Int32 index)
   at MyApp.Views.SearchView.<>c__DisplayClass9_0.<UpdateListViewSelection>b__0()
   at MyApp.Views.SearchView.<>c__DisplayClass10_0.<<ExecuteSafely>b__0>d.MoveNext()
B:

for(int i=0;i

另一种选择是不虚拟化,但那更糟。。。有人知道如何在UWP中安全地清除虚拟化listview上的选择吗?

根据listview的
SelectionMode
清除正确的方式似乎很重要。以下是清除列表视图选择的安全方法(无需关心
SelectionMode
您自己):


如果ListView绑定到IItemsRangeInfo,则此操作无效。在这种情况下,SelectedItems不同步(即通常为空)。您可以使用this.SelectedRanges.ToList().ForEach(iir=>this.deselectedrange(iir));此外,在虚拟化和使用大型数据集时,使用范围而不是项是有意义的,因为这样更有效。顺便说一下,选择项也是如此:我们应该根据控件的SelectionMode分配给SelectedItem或添加到SelectedItems。否则我们将面临同样的“灾难性失败”。
listView.SelectedItems.Clear();
for (int i = 0; i < listView.SelectedItems.Count; i++)
{
    listView.SelectedItems.RemoveAt(i--);
}
public static void ClearSelection(this ListViewBase listView)
{
    Argument.IsNotNull(() => listView);

    switch (listView.SelectionMode)
    {
        case ListViewSelectionMode.None:
            break;

        case ListViewSelectionMode.Single:
            listView.SelectedItem = null;
            break;

        case ListViewSelectionMode.Multiple:
        case ListViewSelectionMode.Extended:
            listView.SelectedItems.Clear();
            break;

        default:
            throw new ArgumentOutOfRangeException();
    }
}