问题
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 ListBoxItem
s, the binding works properly - the custom object's IsSelected
property is updated in my ViewModel. However, if I select all of the ListBoxItem
s with a Ctrl+A command, only the currently visible ListBoxItem
s (those that are currently in my scrolling viewport) update their ViewModel bindings. On the frontend, all the ListBoxItem
s 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 ListBoxItem
s 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.
回答1:
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.
来源:https://stackoverflow.com/questions/17302232/listbox-isselected-binding-only-partially-working