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

时间:2014-04-04 04:56:17

标签: c# wpf listview virtualizingstackpanel

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

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

 <KeyBinding Command="{Binding SelectAllCommand}"
                            Modifiers="Control"
                            Key="A"/>

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

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

Selector的这种行为是可以预料到的,因为它只能在加载的UI元素中运行。由于启用虚拟化,您只加载了包含在可见区域中的元素。所以,Selector并不知道&#34;关于他人。

为了解决这个问题,你必须这样做,选择器&#34;知道&#34;关于以前选择的项目。换句话说,您必须禁止卸载所选的任何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或其他提供选择器的用户控件中的默认面板。 例如,通过样式:

<Setter Property="ItemsPanel">
    <Setter.Value>
        <ItemsPanelTemplate>
            <blackjackandhookers:MyVirtualizingStackPanel/>
        </ItemsPanelTemplate>
    </Setter.Value>
</Setter>

...或者,直接在你的选择器中:

<YourSelector.ItemsPanel>
    <ItemsPanelTemplate>
        <blackjackandhookers:MyVirtualizingStackPanel/>
    </ItemsPanelTemplate>
</YourSelector.ItemsPanel>

享受!

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