DependencyObject还实现了INotifyPropertyChanged?

时间:2014-06-09 17:01:33

标签: c# wpf silverlight inotifypropertychanged dependencyobject

对于Silverlight和WPF应用程序,我有一个自定义控件,其中包含ObservableCollection作为依赖项属性。该控件的一个元素是Border,需要根据ObservableCollection中项目的组成来改变颜色。

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

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

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

挑战在于,当ObjectList添加/删除项目时,我需要触发重新评估背景颜色;但是,ObjectList本身并没有改变。我想我有三个选择,但我不确定哪个可能是最好的做法:

  1. 每次添加或删除对象时都创建一个新集合。这似乎很苛刻,但会导致ObjectList被更改,从而触发后台更新。

  2. UpdateTarget的{​​{1}}回调中调用CollectionChanged背景属性。由于ObjectList不适用于Silverlight,我只需删除并重新添加绑定 - 再次有点沉重。

  3. 在我的自定义控件上实施UpdateTarget,并在INotifyPropertyChanged

  4. 的实施中PropertyChanged上致电ObjectList

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

1 个答案:

答案 0 :(得分:2)

a way of doing this recommended by the MSDN documentation(向下滚动到使用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实例更改更好。