我有时候认为我可能会不必要地使用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行?
答案 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);
}