当在一个模型-视图-视图模型架构的WPF应用程序中实现ViewModel时,似乎有两个主要的选择:如何使它可数据化。我已经看到实现使用DependencyProperty属性的视图要绑定,我已经看到ViewModel实现INotifyPropertyChanged代替。
我的问题是,什么时候我应该更喜欢其中一个?有什么性能差异吗?把ViewModel依赖项交给WPF真的是个好主意吗?在做设计决定时,我还需要考虑什么?
当在一个模型-视图-视图模型架构的WPF应用程序中实现ViewModel时,似乎有两个主要的选择:如何使它可数据化。我已经看到实现使用DependencyProperty属性的视图要绑定,我已经看到ViewModel实现INotifyPropertyChanged代替。
我的问题是,什么时候我应该更喜欢其中一个?有什么性能差异吗?把ViewModel依赖项交给WPF真的是个好主意吗?在做设计决定时,我还需要考虑什么?
当前回答
从表达的角度来看,我非常喜欢使用依赖属性,一想到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中,也可以在其他任何地方。
依赖属性旨在支持在UI元素上绑定(作为目标),而不是作为数据绑定的源,这就是INotifyProperty的作用。从纯粹的角度来看,你不应该在ViewModels上使用DP。
"In order to be the source of a binding, a property does not need to be a dependency property; you can use any CLR property as a binding source. However, in order to be the target of a binding, the property must be a dependency property. For a one-way or two-way binding to be effective, the source property must support change notifications that propagate to the binding system and thus the target. For custom CLR binding sources, this means that the property must support INotifyPropertyChanged. Collections should support INotifyCollectionChanged."
所有依赖对象都不能被序列化(这可能会妨碍ViewModels和DTO (POCO)的使用。
与WPF相比,Silverlight中的DP有一些不同之处。
http://msdn.microsoft.com/en-us/library/cc221408 (v = VS.95) . aspx
http://msdn.microsoft.com/en-us/library/cc903933 (VS.95) . aspx
选择完全取决于您的业务逻辑和UI抽象级别。如果你不想好好分开,那么DP可以帮你。
DependencyProperties将主要适用于VisualElements级别,所以如果我们为每个业务需求创建大量的dp并不是一个好主意。DP的开销也比INotifyPropertyChanged大。当你设计WPF/Silverlight时,试着把UI和ViewModel完全分开,这样我们就可以随时改变布局和UI控件(基于主题和样式)。
请参考这篇文章- https://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel。该链接有很多参考模型-视图-视图模型模式,这与本文的讨论非常相关。
根据WPF性能指南,DependencyObjects肯定比实现INotifyPropertyChanged的POCOs性能更好:
http://msdn.microsoft.com/en-us/library/bb613546.aspx
把ViewModel依赖项交给WPF真的是个好主意吗?
. net 4.0将有System.Xaml.dll,所以你不必依赖于任意的框架来利用它。请参阅Rob Relyea关于他的PDC会议的帖子。
我的看法
XAML是一种描述对象的语言,而WPF是一种框架,其描述对象是UI元素。
它们的关系类似于c#(一种描述逻辑的语言)和。net(一种实现特定类型逻辑的框架)。
XAML的目的是声明性的对象图。W*F技术是这种范例的很好的候选者,但是XAML独立于它们而存在。
XAML和整个依赖系统是作为WF和WPF的独立堆栈实现的,可能是为了利用不同团队的经验,而不会在它们之间创建依赖关系(没有双关语)。