选定的 WPF 列表框绑定仅更新视图中的项目

Posted

技术标签:

【中文标题】选定的 WPF 列表框绑定仅更新视图中的项目【英文标题】:WPF listbox binding selected only updates items in view 【发布时间】:2021-04-16 07:18:39 【问题描述】:

我在使用 WPF 和 MVVM 的 UserControl 中遇到了一个奇怪的问题。列表框的项目通过 ViewModel 和 ObservableCollection<T> 绑定,样式属性 IsSelected 绑定到单个项目内的属性 Selected

[...]
<ListBox ItemsSource="Binding Path=SQLObjects" FontFamily="Consolas" Margin="5,0,5,5" DisplayMemberPath="Name" SelectionMode="Extended" SelectedItem="Binding Path=SelectedSQLObject">
    <ListBox.Resources>
        <Style TargetType="x:Type ListBoxItem" BasedOn="StaticResource MetroListBoxItem">
            <Setter Property="IsSelected" Value="Binding Selected, Mode=TwoWay" />
        </Style>
    </ListBox.Resources>
</ListBox>
[...]

当用户选择单个或多个项目(使用 ctrl 或 shift)时,属性会按预期更新。但是选择所有带有ctrl + a 的项目只会更新列表框滚动区域内可见项目的Selected 属性。

在屏幕截图中,所有项目均使用ctrl + a 选择,但只有当前可见的项目的属性已更新。在列表框中向下滚动而不更改选择时,所有项目都会在它们出现时更新。

这可能是由MahApps.Metro引起的吗?

ViewModel 绑定到主窗口中 xaml 内的 UserControls Datacontext。

[...]
<TabItem Header="Trigger">
    <userControls:ObjectControl>
        <userControls:ObjectControl.DataContext>
            <viewmodel:TriggerObjectViewModel DialogCoordinator="x:Static local:MainWindow.Coordinator" />
        </userControls:ObjectControl.DataContext>
    </userControls:ObjectControl>
</TabItem>
[...]

所有其他 TabItems 使用相同的用户控件并且有相同的问题。

我不想使用解决方法(例如,当用户在当前视图之外选择项目时滚动整个列表),是否可以为 WPF 设置任何类型的属性来更新集合内的所有项目,不管它们是否可见?

【问题讨论】:

【参考方案1】:

我怀疑这是由于虚拟化造成的。 UI 项在滚动到视图中之前不存在。

尝试关闭列表控件上的虚拟化:

<ListBox ItemsSource="Binding Path=SQLObjects"
         VirtualizingPanel.IsVirtualizing="False">

【讨论】:

不,不是这样。我还尝试设置不同的虚拟化属性(缓存或容器虚拟化),但问题仍然存在。 MSDN 声明,当IsVirtualizing="False" 时应禁用虚拟化。有没有办法检查列表框是否被虚拟化? 我做错了,我更改了错误的通用用户控件来测试虚拟化行为。您的解决方案有效,谢谢。

以上是关于选定的 WPF 列表框绑定仅更新视图中的项目的主要内容,如果未能解决你的问题,请参考以下文章

WPF - 绑定到用户控件之间的列表框的选定项

WPF Master-Details 视图与列表框和组合框与绑定

删除列表框中的多个选定项目 - 仅识别第一个选择的代码

WPF将单个文本框绑定到集合对象或数组中的元素

如何将 DataGrid 中的文本框绑定到 Wpf 中的列表?

WPF:仅当列表框中的一项被选中时才启用按钮