当在一个模型-视图-视图模型架构的WPF应用程序中实现ViewModel时,似乎有两个主要的选择:如何使它可数据化。我已经看到实现使用DependencyProperty属性的视图要绑定,我已经看到ViewModel实现INotifyPropertyChanged代替。
我的问题是,什么时候我应该更喜欢其中一个?有什么性能差异吗?把ViewModel依赖项交给WPF真的是个好主意吗?在做设计决定时,我还需要考虑什么?
当在一个模型-视图-视图模型架构的WPF应用程序中实现ViewModel时,似乎有两个主要的选择:如何使它可数据化。我已经看到实现使用DependencyProperty属性的视图要绑定,我已经看到ViewModel实现INotifyPropertyChanged代替。
我的问题是,什么时候我应该更喜欢其中一个?有什么性能差异吗?把ViewModel依赖项交给WPF真的是个好主意吗?在做设计决定时,我还需要考虑什么?
当前回答
从表达的角度来看,我非常喜欢使用依赖属性,一想到INotifyPropertyChanged就畏缩。除了字符串属性名和由于事件订阅可能导致的内存泄漏之外,INotifyPropertyChanged是一种更显式的机制。
依赖属性意味着使用易于理解的静态元数据“当这个时,做那个”。这是一种声明性的方法,我认为它很优雅。
其他回答
从表达的角度来看,我非常喜欢使用依赖属性,一想到INotifyPropertyChanged就畏缩。除了字符串属性名和由于事件订阅可能导致的内存泄漏之外,INotifyPropertyChanged是一种更显式的机制。
依赖属性意味着使用易于理解的静态元数据“当这个时,做那个”。这是一种声明性的方法,我认为它很优雅。
INotifyPropertyChanged在使用时还允许您在属性的getter和setter的代码中添加更多逻辑。
DependencyProperty例子:
public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );
public String Name
{
set { SetValue( NameProperty, value ); }
get { return ( String ) GetValue( NameProperty ); }
}
在你的getter和setter中——你所能做的就是分别调用SetValue和GetValue, b/c在框架的其他部分,getter/setter不会被调用,而是直接调用SetValue和GetValue,所以你的属性逻辑不会可靠地执行。
使用INotifyPropertyChanged定义一个事件:
public event PropertyChangedEventHandler PropertyChanged;
然后简单地在你的代码的任何地方有任何逻辑,然后调用:
// ...
// Something cool...
// ...
if( this.PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}
// More cool stuff that will reliably happen...
它可以在getter/setter中,也可以在其他任何地方。
根据WPF性能指南,DependencyObjects肯定比实现INotifyPropertyChanged的POCOs性能更好:
http://msdn.microsoft.com/en-us/library/bb613546.aspx
最近我也不得不考虑这个决定。
我发现INotifyPropertyChanged机制更适合我的需求,因为它允许我将GUI粘到现有的业务逻辑框架上,而不需要复制状态。我使用的框架有自己的观察者模式,很容易将一个级别的通知转发到下一个级别。我有一个简单的类,它实现了来自业务逻辑框架的观察者接口和INotifyPropertyChanged接口。
使用DP,您不能自己定义存储状态的后端。我将不得不让。net缓存我所绑定的每个状态项的副本。这似乎是一个不必要的开销-我的状态是大而复杂的。
因此,在这里我发现INotifyPropertyChanged更适合将属性从业务逻辑公开到GUI。
也就是说,我需要一个自定义GUI小部件来公开一个属性,并对该属性进行更改以影响其他GUI小部件DP证明了简单的解决方案。
所以我发现DP对于GUI到GUI的通知很有用。
选择DependencyObject的原因只有一个——绑定会工作得更好。只是尝试一个ListBox和TextBox的例子,用INotifyPropertyChanged属性与DependencyProperty的数据填充列表,并从TextBox编辑当前项目…