Couldn't get selected items correctly if setting ListView ItemsContainer as VirtualizationStackPanel

天大地大妈咪最大 提交于 2019-11-28 07:07:13

问题


I set 'VirtualizingStackPanel.IsVirtualizing' to true and 'VirtualizingStackPanel.VirtualizationMode' to 'Recycling', because the items in my ListView are too many. The SelectionMode of the ListView is Extended, the 'IsSelected' property of the ListViewItem is bound to 'IsSelected' property of my model, bind mode is two way.

When I want to use Ctrl+A to select all of the items, it only select part of the items, so I use KeyBinding to write the select all method like below:

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

SelectAll method will loop the ItemsSource collection and set each of the item's IsSelected property to true. But it also leads to something unexpected. When all of the items are selected, I scroll the scrollbar to the bottom and it will load more items to the ListView, I single click one item and the expected is all other items are unselected, only select this item. But, it seems not unselect other items.

Anybody can help?


回答1:


This behaviour of the Selector is to be expected, because it can operate only with loaded UI elements. Due enabling virtualization you have loaded only those elements which contains in visible area. So, Selector does not "know" about others.

For fix this you must do so, that Selector "know" about previously selected items. In other word, you must to prohibit unloading any UI element which was selected.

First, create own virtualizing panel with blackjack and hookers:

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);
    }
}

Next, replace default panel in the ListBox, ListView, TreeView or other user controls which provide selector. For example, via style:

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

... or, directly in your selector:

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

Enjoy!

I hope my answer will help you.



来源:https://stackoverflow.com/questions/22853896/couldnt-get-selected-items-correctly-if-setting-listview-itemscontainer-as-virt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!