大家对于何时在视图模型中使用触发 INotifyPropertyChanged.PropertyChanged
的简单 .NET 属性有什么指导意见吗?那么,何时需要升级为完整的依赖属性呢?或者说,依赖属性主要是用于视图吗?
大家对于何时在视图模型中使用触发 INotifyPropertyChanged.PropertyChanged
的简单 .NET 属性有什么指导意见吗?那么,何时需要升级为完整的依赖属性呢?或者说,依赖属性主要是用于视图吗?
有几种方法:
1. 依赖属性
当你使用依赖属性时,它最适用于具有视觉外观的元素类(UIElement
)。
优点:
缺点:
DependencyObject
派生出来示例:
public static class StoryBoardHelper
{
public static DependencyObject GetTarget(Timeline timeline)
{
if (timeline == null)
throw new ArgumentNullException("timeline");
return timeline.GetValue(TargetProperty) as DependencyObject;
}
public static void SetTarget(Timeline timeline, DependencyObject value)
{
if (timeline == null)
throw new ArgumentNullException("timeline");
timeline.SetValue(TargetProperty, value);
}
public static readonly DependencyProperty TargetProperty =
DependencyProperty.RegisterAttached(
"Target",
typeof(DependencyObject),
typeof(Timeline),
new PropertyMetadata(null, OnTargetPropertyChanged));
private static void OnTargetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Storyboard.SetTarget(d as Timeline, e.NewValue as DependencyObject);
}
}
2. System.ComponentModel.INotifyPropertyChanged
通常,在创建数据对象时,您将使用此方法。这是一种针对类似数据的东西的简单而整洁的解决方案。
优缺点-与1相辅相成。 您只需要实现一个事件(PropertyChanged)。
示例:
public class Student : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
private string name;
public string Name;
{
get { return name; }
set {
name = value;
OnPropertyChanged(new PropertyChangedEventArgs("Name"));
}
}
3. PropertyNameChanged
针对每个指定名称的属性(例如 NameChanged),触发一个事件。这个事件必须具有该名称,你需要处理/触发它们。类似于第2种方法。
4. 获取绑定关系
使用FrameworkElement.GetBindingExpression()
可以获取BindingExpression
对象,
并调用BindingExpression.UpdateTarget()
进行刷新。
第一种和第二种方法最有可能取决于你的目标。
总之,它是视觉与数据之间的区别。
DependencyProperty
仅在以下情况下需要使用:
普通属性无法提供这些功能。
DependencyProperty
是必须的,如果您想允许在属性上设置绑定。通常这是用于您创建的自定义 UIElement
。您希望允许用户能够将数据绑定到您的 UIElement
。
<local:MyUIElement MyProperty={Binding Path=SomethingToBindTo} />
INotifyPropertyChanged
很多次,你的回答中有没有任何“隐藏的方面”是不明确的? - Daniel MöllerINotifyPropertyChanged
的主要问题在于,如果您的视图模型很复杂,包含许多嵌套类型,那么似乎您必须通过层次结构向上冒泡PropertyChanged
事件。