何时使用依赖属性

时间:2010-11-05 07:31:53

标签: c# wpf dependency-properties

我有时候认为我可能会不必要地使用Dependency Properties。我什么时候需要使用它?当我有一个依赖于其他属性的属性?假设我有一个Color属性,我希望它依赖于属性Hue,Saturation,Luminosity我是否使用依赖属性?或者我用什么?当属性色调,饱和度,亮度发生变化时,我控制绑定到Color的那些更新。

现在我做的是

public byte Hue {
    get { return _hue; }
    set
    {
        if (_hue == value)
            return;
        _hue = value;
        NotifyPropertyChanged("Hue");
        NotifyPropertyChanged("Color"); // to update controls bound to color
    }
}

但我认为这不是正确的做事方式?如果我有更多影响颜色的属性,我将在所有这些属性中增加1行?

5 个答案:

答案 0 :(得分:21)

当您希望能够通过XAML将值绑定到某个内容时,您应该只使用DependencyProperty,例如

<local:MyObject MyDependencyProperty="{Binding ...}" />

更新:如下面的Ian所述,如果您希望能够为您的属性设置动画或通过样式设置它,还需要依赖项属性

如果您不需要以这种方式工作,那么就没有必要了。例如如果您只是希望能够通过XAML将值设置为常量(如下所示),则无需使用DependencyProperty

<local:MyObject MyRegularProperty="Some Value" />

同样,如果要将绑定到(例如)视图模型上的属性值:

<TextBlock Text="{Binding MyViewModelProperty}" />

然后您不需要使用DependencyProperty。如果您实施INotifyPropertyChanged,则在属性更改时仍会更新Text

编辑重新阅读您的问题,我不确定您的情况是否会受到DependencyProperty的影响 - 如果我正在阅读它正确地说,你想要做的就是当这些属性中的任何一个发生变化时,在UI上更新许多属性,对吗?

我认为你目前的实施方式没有任何问题(即在每个人中引发很多PropertyChanged个事件),但如果你不热衷于此,你可以尝试使用一个属性来公开要绑定的相关子属性,这些属性都是计算出来的:

class ColorWrapper
{
    public Color Color  { get; set; }
    public byte Hue
    {
        get { return this.Color.Hue; } //or however this is calculated
}

然后在ViewModel上有一个Color属性,它会引发PropertyChanged事件并通过视图绑定到该事件:

<TextBlock Text="{Binding Color.Hue}" />

正如我所说,我不会说这对你已经拥有的东西特别有所改善。

答案 1 :(得分:15)

一般规则是:

  • 对于XAML控件,请使用依赖项属性;

  • 对于数据(您在界面中绑定),请使用INotifyPropertyChanged

有例外,但很少见。

答案 2 :(得分:2)

依赖属性的另一个用途是使用导航日志。在元数据中具有Juornal标志的页面上的自定义依赖项属性包含在WPF为页面保存的状态中。

答案 3 :(得分:0)

请记住,依赖属性虽然允许Binding作为源或目标,但也是线程敏感的,并且在序列化时您必须使用代理,序列化作为DependencyObject不可序列化。

哦,Equals和GetHashCode是密封的:(

答案 4 :(得分:0)

DP的另一种用法是“附加属性”。附加属性是DependencyProperty的一种,其中该属性可在任何其他控件中使用。 例如,您可以在类MyAttachedProperties中声明AttachedProperty,并将其用于TextBlock,Button,Label,...

附加属性的一些示例:Grid.Row,Grid.Column。定制的:

public static readonly DependencyProperty DarkThemeProperty =
    DependencyProperty.RegisterAttached("DarkTheme", typeof(Theme), typeof(Page));
 
public static Theme GetDarkTheme(DependencyObject obj)
{
    return (Theme)obj.GetValue(DarkThemeProperty);
}
 
public static void SetDarkTheme(DependencyObject obj, Theme value)
{
    obj.SetValue(DarkThemeProperty, value);
}