Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listbox "IsSelected" binding only partially working

I have a ListBox that I populate dynamically via a binding (this is defined in a DataTemplate, which is why the binding is somewhat unusual):

<ListBox SelectionMode="Extended" ItemsSource="{Binding DataContext.ResultList, RelativeSource={RelativeSource AncestorType=Window}}">
  <ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
      <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
    </Style>
  </ListBox.ItemContainerStyle>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Label Content="{Binding Object}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Each ListBoxItem's IsSelected property is bound to an IsSelected property on a custom object.

When I select individual ListBoxItems, the binding works properly - the custom object's IsSelected property is updated in my ViewModel. However, if I select all of the ListBoxItems with a Ctrl+A command, only the currently visible ListBoxItems (those that are currently in my scrolling viewport) update their ViewModel bindings. On the frontend, all the ListBoxItems appear to be selected, and the ListBox.SelectedItems.Count property on the container ListBox shows that all items are selected.

Furthermore, as I scroll through the ListBox after selecting all ListBoxItems with Ctrl+A, the bindings are successfully updated when each ListBoxItem is scrolled into view.

Why does this binding seem to be only partially working? Is there a better way to handle the binding of the IsSelected property when large numbers of ListBoxItems can be selected simultaneously?

Edit: This behavior doesn't happen exclusively with the Ctrl+A command - I get the same results when selecting all the items using a shift+click.

like image 714
Nathan Friend Avatar asked Jun 25 '13 16:06

Nathan Friend


1 Answers

I think the behavior you're seeing is to due to VirtualizingStackPanel.IsVirtualizing which is True by default when binding to ItemsSource of ListBox

if you for eg set your ListBox such as:

<ListBox VirtualizingStackPanel.IsVirtualizing="False" SelectionMode="Extended" ItemsSource="{Binding DataContext.ResultList, RelativeSource={RelativeSource AncestorType=Window}}">

or

<ListBox ...>
  ...
  <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel />
    </ItemsPanelTemplate>
  </ListBox.ItemsPanel>
</ListBox>

then you should see all your bound items have their IsSelected updated accordingly with Ctrl+A or Shift + ...

Properties such as Count of the collection even with virtualization would report the correct value to accommodate for things like computing the required ScrollBar.Height. Items which are outside the View-port do not get rendered hence no bindings are in effect on them until they actually get used.

like image 159
Viv Avatar answered Oct 20 '22 11:10

Viv