1

I'm having performance issues in ListBox when deselecting large groups of items. My ListBox currently contains 90,000+ items.

I believe the performance issue is because SelectedItems is represented by a List instead of a HashSet.

What would be the easiest way to recreate ListBox functionality, support multiselection, and implement selecteditems as a hashset.

I would not need to support selectedindex, which I think is why the selecteditems is a list.

Lee Louviere
  • 4,960
  • 28
  • 51

2 Answers2

1

you should find a way to virtualize the ListBox so that not all elements will be loaded in memory and added to the list at once, instead the footprint of the control will only contain the elements currently visible and load others only when scrolling, some kind of web-like load on demand...

This answer describes the issue in details: https://stackoverflow.com/a/2784220/559144

and this link is very helpful: Optimizing Performance: Controls

it tells you that WPF ListBox actually does support virtualization by desfault and that you can additionally enable:

  • Container recycling
  • Deferred scrolling
Community
  • 1
  • 1
Davide Piras
  • 42,120
  • 10
  • 86
  • 140
  • If you shift-select everything in the ListBox, then click on one item, the control has to remove all those unselected items from the SelectedItems List<>. **The List<> has O(n) for removing items. That's the issue.** If ListBox employed HashSet<> to store off selection, removing items from selection would be O(1). I understand what virtualization does, but it doesn't eliminate the data itself. My problem is with the data. I could have no control at all, and if I were using a class with a List<> and removed every item one at a time, it would be just as slow. – Lee Louviere Apr 17 '13 at 16:29
0

What I did was create a class that manages selection, stores off selection as a HashMap. Then I handled the MouseDown on the ListBoxItem and imitated shift and ctrl selecting.

I changed selection to single and basically ignored the default selection reflexes.

Here is my XAML.

<ListBox Margin="2" 
 Grid.Column="0" 
 Name="WordList" 
 ItemsSource="{Binding Source={StaticResource CVS}}"
 SelectionMode="Single">
   <ListBox.ItemContainerStyle>
      <Style TargetType="{x:Type ListBoxItem}">
         <EventSetter Event="PreviewMouseDown" Handler="Clicked"/>
         <EventSetter Event="PreviewMouseMove" Handler="MouseMoved"/>
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="{x:Type ListBoxItem}">
                  <TextBlock Name="Text" Text="{Binding Word}"/>
                  <ControlTemplate.Triggers>
                     <DataTrigger Binding="{Binding IsSelected}" Value="True">
                        <Setter TargetName="Text" Property="Background" Value="LightBlue"/>
                     </DataTrigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
   </ListBox.ItemContainerStyle>

Lee Louviere
  • 4,960
  • 28
  • 51