列表框" IsSelected"绑定只是部分工作

时间:2013-06-25 16:07:04

标签: wpf mvvm binding listbox listboxitem

我有ListBox我通过绑定动态填充(这是在DataTemplate中定义的,这就是绑定有点不寻常的原因):

<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>

每个ListBoxItem的{​​{1}}属性都绑定到自定义对象上的IsSelected属性。

当我选择单个IsSelected时,绑定正常工作 - 自定义对象的ListBoxItem属性在我的ViewModel中更新。但是,如果我使用Ctrl + A命令选择所有IsSelected,则只有当前可见的ListBoxItem(当前位于我的滚动视口中)更新其ViewModel绑定。在前端,所有ListBoxItem似乎都被选中,容器ListBoxItem上的ListBox.SelectedItems.Count属性显示所有项都被选中。

此外,当我使用Ctrl + A选择所有ListBox后滚动浏览ListBox时,当每个ListBoxItem滚动到视图中时,绑定会成功更新。

为什么这种绑定似乎只是部分有效?当可以同时选择大量ListBoxItem时,是否有更好的方法来处理IsSelected属性的绑定?

修改 这种行为不会仅使用Ctrl + A命令发生 - 当使用shift + click选择所有项目时,我得到相同的结果。

1 个答案:

答案 0 :(得分:5)

我认为您所看到的行为归因于VirtualizingStackPanel.IsVirtualizing,在绑定True ItemsSource时默认为ListBox

如果你设置你的ListBox,例如:

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

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

然后您应该看到所有绑定的项目都使用Ctrl + A或Shift +相应地更新了IsSelected ...

即使使用虚拟化,集合的Count等属性也会报告正确的值,以适应计算所需ScrollBar.Height之类的内容。 View-port之外的项目不会被渲染,因此在实际使用之前,没有任何绑定对它们有效。