1

我的应用程序有一个后台线程,它定期以键/值对的形式从外部源检索数据。我想公开这些数据以进行绑定,大概是通过将它们存储在某种静态(?)模型中,因为我的应用程序中的许多视图都需要这些数据。可能有数百个这样的键,并且每个客户可能不同,所以我不能简单地创建一个 INotifyPropertyChanged 模型,其中每个值都有一个属性。

该应用程序在任何时候都有多个可见的视图,每个视图都有许多控件(通常是文本框),我想将它们绑定到上述集合中的各个项目。当集合中的值更新时,任何绑定到该项目的控件应该更改以反映新值。我假设ObservableCollection这里不适合,因为对单个项目的更改将导致所有控件更新,无论它们绑定到哪个项目?

为了使组合更加复杂,某些值(数字)将需要格式化以进行显示,例如小数位数,或添加诸如“伏特”之类的后缀。格式化规则是用户定义的,所以我不能将它们硬编码到(比如说)XAML 绑定的StringFormat表达式中。理想情况下,我应该能够访问原始值(例如用于计算)和格式化版本(用于显示目的)。我敢肯定,使用一些巧妙的 WPF 功能一定可以实现后者!

我将不胜感激有关如何解决这些要求的任何指示。

编辑:值得一提的是,我之前曾尝试将模型实现为某种集合。问题是它最初不会填充所有值,并且这些只是在一段时间后才添加。当它们最终被添加时,绑定控件不会更新 - 大概是因为它最初无法绑定到缺失值。

4

3 回答 3

1

我会采取不同的方法,即Event Aggregation的变体。我将有一个管理整个集合的类(可能是一个像 franssu 建议的单例类),但不是直接绑定到该类中的集合,而是创建更小的模型,这些模型更特定于各个视图。

当您的主模型收到一个新项目时,它会发布一个事件,该事件由较小的模型使用,这些模型可以检查新项目并确定是否应该将该项目添加到其内部集合(单个视图绑定到的集合) )。如果它不“属于”他们的观点,他们可以简单地忽略该事件。

您可以使用类似的事件发布来更新项目等,但如果您绑定到实际项目,您可能不需要它。

于 2012-08-23T13:04:44.627 回答
1

只需实现INotifyCollectionChanged接口,INotifyPropertyChanged你就会得到一个像 ObservableCollection 这样的集合。

但是请记住,如果您从您的集合中选择一个项目(例如 ObservableCollection)并且您更改了该项目,您的其他控件将不会更新。因此,如果您的 Collection 中有一个 Person 类,并且您更改了一个人的名字,那么其他控件将不会获得该人的新名字。

在 Person 对象中,您仍然必须实现INotifyPropertyChanged接口并在名称更改时引发事件。

所以我想告诉你的是:带有界面的集合INotifyCollectionChanged只会告诉绑定的控件:有一个新项目,有一个项目被删除或项目索引发生变化,但如果项目本身发生变化,则不会。

因此,您将需要一个提供上述要点的 Collection 和一个包含在该集合中的 Item,如果它的属性发生更改则引发事件。

于 2012-08-23T13:05:46.650 回答
0

ObservableCollection这里很完美。您应该会发现ItemsControl绑定到 an的标准ObservableCollection只会更新已更改项目的控件,而不是集合中的每个项目。

这就是ObservableCollection存在的原因 - 它引发的事件专门识别已更改的项目,以便 UI 可以明智地处理它们。

我已经用一个小型 WPF 应用程序在本地对此进行了测试,它运行良好。不过,值得注意的是,虚拟化项目面板在滚动时可能会破坏这种行为......

编辑:重新阅读您的问题,您实际上是说“当集合中的值被更新时......”如果您的集合包含一个类的实例,并且您更新了该类的属性,您甚至不需要ObservableCollection这个工作 -你只需要类来实现INotifyPropertyChanged

于 2012-08-23T13:05:44.770 回答