Failed to get selected items correctly if set ListView ItemsContainer as VirtualizationStackPanel

I set "VirtualizingStackPanel.IsVirtualizing" to true and "VirtualizingStackPanel.VirtualizationMode" to "Recycling" because there are too many items in my ListView. The SelectionMode element in the ListView is expanded, the IsSelected property for the ListViewItem is bound to the IsSelected property of my model, the binding mode is in two ways.

When I want to use Ctrl + A to select all the elements, it selects only part of the elements, so I use KeyBinding to write the select all method, as shown below:

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

The SelectAll method will loop through the ItemsSource collection and set each IsSelected property to true. But it also leads to something unexpected. When all the elements are selected, I scroll the scroll bar to the bottom and it will load more elements in the ListView, I click one element on one element, and the expected one - all other elements are not selected, just select this element. But it does not seem to unselect the other elements.

Can anybody help?

0
c # listview wpf virtualizingstackpanel
Apr 04 '14 at 4:56
source share
1 answer

This selector behavior is to be expected since it can only work with loaded user interface elements. Thanks to the possibility of virtualization, you have loaded only those elements that are contained in the visible area. Thus, the selector does not β€œknow” about others.

To fix this, you must do this so that the Selector β€œknows” about previously selected items. In other words, you must prevent the unloading of any user interface element that has been selected.

First, create your own virtualization panel with blackjack and prostitutes:

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

Then replace the default panel in ListBox, ListView, TreeView, or other custom controls that provide a selector. For example, through the 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 it!

Hope my answer helps you.

0
Apr 09 '15 at 18:04
source share



All Articles