【发布时间】:2014-07-30 06:42:41
【问题描述】:
对于 Silverlight 和 WPF 应用程序,我有一个自定义控件,其中包含一个 ObservableCollection 作为依赖项属性。该控件的一个元素 Border 需要根据 ObservableCollection 中项目的组成来改变颜色。
例如,假设集合是动物、蔬菜和矿物,名为ObjectList。如果至少有一只动物,我希望边框是红色的;如果没有动物,但至少有一种蔬菜,它是绿色的;否则集合中只有矿物,所以会显示为蓝色。
我创建了一个转换器,它可以获取集合并确定颜色,所以有一个像这样的绑定:
<Border Background="{Binding ObjectList,
RelativeSource={RelativeSource Self},
Converter={StaticResource MyColorConverter}}" />
挑战在于,当从ObjectList 添加/删除项目时,我需要触发对背景颜色的重新评估;但是,ObjectList 本身并没有改变。我想我有三个选项,但不确定哪个可能是最佳做法:
每次添加或删除对象时创建一个新集合。这看起来很严厉,但会导致
ObjectList被更改,从而触发后台更新。在
ObjectList的CollectionChanged回调中为背景属性调用UpdateTarget。由于UpdateTarget不适用于 Silverlight,我只是删除并重新添加绑定 - 再次有点笨拙。在我的自定义控件上实现
INotifyPropertyChanged并在ObjectList的实现中调用PropertyChangedCollectionChanged
我最喜欢 3,但事实上我有一个也实现 INPC 的 DependencyObject 似乎很奇怪。是吗?有没有更优雅的方法?
【问题讨论】:
-
第 3 点是一个轻量级解决方案,在这三个解决方案中,它之所以引人注目。对于我自己,我会将背景绑定到您控件中的附加 DP,然后根据 ObjectList 的更改对其进行更新。由于 ObservableCollection 继承自 IList,因此底层的 ListCollectionView 非常有用。
-
我实际上忽略了那个,我正在使用一个额外的 DP,但它看起来就像另一个(冗余)移动部件,仍然需要以某种方式“改变”
-
当您的集合变大时,您可能不会意识到更新列表属性对性能的影响。此外,如果列表在 Animal 上被过滤,并且您添加了新的 Mineral,那么您将迭代整个列表。所以它不一定是多余的,这取决于你希望你的控制有多复杂。
标签: c# wpf silverlight inotifypropertychanged dependencyobject