绑定到集合是如何真正起作用的?

Posted

技术标签:

【中文标题】绑定到集合是如何真正起作用的?【英文标题】:How does binding to collections really work? 【发布时间】:2012-12-06 14:26:32 【问题描述】:

好吧,我很困惑。

如果我的控件具有 IEnumerable 类型的依赖属性 ItemsSource 并且用户将集合绑定到它,我在 DependencyPropertyChangedEventArgs.NewValue 中有什么对象?

据我所知CollectionView 是为集合隐式创建的,我希望args.NewValue 的类型为ICollectionView

来自this blog:

当用户将 WPF 属性绑定到数据集合时,WPF 自动创建一个视图来包装集合,并绑定 视图的属性,而不是原始集合。这种行为总是 发生,并且独立于 CollectionViewSource。

但调试器(VS 2012,.net v.4.0)显示我在NewValue 收到原始原始集合。 (BindsDirectlyToSource 未设置,默认为 false) 这怎么可能?!

我无法理解在这种情况下 WPF 控件如何支持排序、分组和过滤。 CollectionView 是如何以及何时注入和使用的?

【问题讨论】:

【参考方案1】:

也许CollectionView 中“备注”部分的以下摘录回答了您的问题:

在 WPF 应用程序中,所有集合都有一个关联的默认值 集合视图。而不是直接使用该系列, 绑定引擎总是通过关联的 看法。要获取默认视图,请使用 CollectionViewSource.GetDefaultView 方法。基于内部类 CollectionView 是仅实现的集合的默认视图 可数的。 ListCollectionView 是集合的默认视图 实现 IList。 BindingListCollectionView 是默认视图 对于实现 IBindingListView 或 IBindingList 的集合。

或者,您可以在 Extensible 中创建集合的视图 使用 CollectionViewSource 的应用程序标记语言 (XAML) 类,然后将您的控件绑定到该视图。这 CollectionViewSource 类是 集合视图类。有关示例,请参阅如何:对数据进行排序和分组 在 XAML 中使用视图。

因此,如果您没有显式绑定到 CollectionViewSource,则始终对原始集合进行集合绑定(您在 NewValue 中获得的内容),但对集合的访问(例如通过索引获取项目)是 总是通过默认视图完成。因此,“将属性绑定到视图,而不是原始集合”的说法并不完全正确。

快速测试显示,GetDefaultView 为我绑定的 ObservableCollection 返回一个 System.Windows.Data.ListCollectionView。

【讨论】:

所以这意味着我的控件必须请求 CollectionView 以获取传递的集合,并且不支持开箱即用的分组、过滤和排序。实现上述功能是控件的责任,不是吗? 当您显式绑定到CollectionViewSource 时,对分组、过滤和排序提供了开箱即用的支持。请参阅Binding to Collections中的“如何创建视图” 我相信仅用于文件过滤和排序。您自己的控件将如何了解已创建的组?好的,假设它只是获取组,但在这种情况下源集合的项目不可用。 见Grouping,上面写着Except for the internal class that views an IEnumerable collection, all collection views support the functionality of grouping 嗯,List/BindingListCollectionView 肯定可以。问题是关于我自己的控制。当它的属性绑定到 CollectionView 时,它仍然必须知道如何使用组。

以上是关于绑定到集合是如何真正起作用的?的主要内容,如果未能解决你的问题,请参考以下文章

为啥是 Ctrl+.当我将它绑定到 Emacs 中的命令时不起作用?

Vue.js - 选择/下拉选定项 vm 绑定不起作用(bootstrap-vue)

正确单击数据网格中的按钮时,Telerik RadGridView 选定项绑定不起作用

绑定不起作用 - 如何?

isAuthenticated() 如何真正起作用?

组合框项目源绑定不起作用