0

ObservableCollection对于 Silverlight 和 WPF 应用程序,我有一个包含作为依赖项属性的自定义控件。该控件的一个元素 Border 需要根据ObservableCollection.

例如,假设集合是动物、蔬菜和矿物质,并称为ObjectList. 如果至少有一只动物,我希望边框是红色的;如果没有动物,但至少有一种蔬菜,它是绿色的;否则该集合只有矿物,因此将显示为蓝色。

我创建了一个可以获取集合并确定颜色的转换器,因此具有如下绑定:

<Border Background="{Binding ObjectList, 
                     RelativeSource={RelativeSource Self}, 
                     Converter={StaticResource MyColorConverter}}" />

挑战在于,随着项目的添加/删除,ObjectList我需要触发对背景颜色的重新评估;然而,ObjectList它本身并没有改变。我想我有三个选择,但不确定哪个可能是最佳实践:

  1. 每次添加或删除对象时创建一个新集合。这似乎很严厉,但会导致ObjectList被更改并因此触发后台更新。

  2. 在回调中调用UpdateTargetbackground 属性。由于不适用于 Silverlight,我只是删除并重新添加绑定 - 再次有点笨拙。CollectionChangedObjectListUpdateTarget

  3. 在我的INotifyPropertyChanged自定义控件PropertyChanged上实现并调用ObjectListCollectionChanged

我最喜欢 3,但事实上我有一个也实现 INPC 的 DependencyObject 似乎很奇怪。是吗?有没有更优雅的方法?

4

1 回答 1

2

MSDN 文档推荐了一种执行此操作的方法(向下滚动到使用 VisualStateManager 的最佳实践;它是为完整的 .Net 编写的,但本节也非常适合 Silverlight)。每当您VisualStates依赖自定义的属性/状态时,Control建议为每个影响 VisualState 的属性设置一个 ChangedHandler 并UpdateVisualStates从那里调用一个私有方法。评估您的条件并VisualStates在此方法中以编程方式设置。

即使您不使用VisualStates颜色更改,我也建议您遵循相同的模式。

为简洁起见,以下代码不完整:

public ObservableCollection ObjectList {...}
public static readonly DependencyProperty ObjectListProperty =
    DependencyProperty.Register(...OnObjectListChanged...);

private static void OnObjectListChanged(...)
{ObjectList.CollectionChanged += OnObjectListCollectionChanged;}

private void OnObjectListCollectionChanged(...){ UpdateVisualStates(); }

private void UpdateVisualStates()
{
    //actually you have to instatiate a SolidColorBrush here
    if (ContainsAtLeastOneAnimal()) { m_border.Background = Colors.Red; }
    else if (ContainsAtLeastOneVegetable()) {m_border.Background = Colors.Green;}
    else { m_border.Background = Colors.Blue; }
}

如果您不想引用边框,请随意引入 DependencyProperty BorderColor并从您的 xaml 绑定到它。没关系。拥有另一个移动部件确实没有问题。这比模拟整个 ObjectList 实例更改要好得多。

于 2014-06-10T09:35:46.740 回答