MVVM模型应该是什么样的?
你好,我有3个关于MVVM模型的问题MVVM模型应该是什么样的?,mvvm,model,poco,inotifypropertychanged,idataerrorinfo,Mvvm,Model,Poco,Inotifypropertychanged,Idataerrorinfo,你好,我有3个关于MVVM模型的问题 有没有办法绕过冗余的PropertyChanged(“PropName”) 将POCO对象包装到WPFINotifyPropertyChanged,IDataErrorInfo 我应该如何与(WPfWrapers-POCO)内部ViewModel交互-通过强制转换或属性 谢谢 是的,您可以使用Lamdba表达式来实现这一点。但这将花费一些处理器时间(进行了一些快速测量:这种方法比使用字符串常量慢大约200倍。在频繁访问的POCO上使用表达式时请记住这一点):
PropertyChanged(“PropName”)代码>
INotifyPropertyChanged,IDataErrorInfo
私有字符串ExtractPropertyName(表达式PropertyExpression)
{
if(PropertyExpression==null)
{
抛出新ArgumentNullException(“PropertyExpression”);
}
var memberExpression=propertyExpression.Body作为memberExpression;
if(memberExpression==null)
{
抛出新ArgumentException(“表达式不是成员访问表达式。”,“PropertyExpression”);
}
var property=memberExpression.Member作为PropertyInfo;
if(属性==null)
{
抛出新ArgumentException(“成员访问表达式不访问属性。”,“PropertyExpression”);
}
如果(!property.DeclaringType.IsAssignableFrom(this.GetType()))
{
抛出新ArgumentException(“引用的属性属于其他类型。”,“PropertyExpression”);
}
var getMethod=property.getMethod(true);
if(getMethod==null)
{
//这不应该发生-表达式将在达到此程度之前拒绝该属性
抛出新ArgumentException(“引用的属性没有get方法。”,“PropertyExpression”);
}
if(getMethod.IsStatic)
{
抛出新ArgumentException(“引用的属性是静态属性。”,“PropertyExpression”);
}
返回memberExpression.Member.Name;
}
私有财产;
公共字符串MyProperty
{
得到
{
归还我的财产;
}
设置
{
myProperty=值;
this.raiseProperty已更改(()=>MyProperty);
}
}
受保护的void RaisePropertyChanged(表达式属性Expression)
{
var propertyName=ExtractPropertyName(propertyExpression);
this.RaisePropertyChanged(propertyName);
}
更多信息可在此处找到:还可以选择在viewmodel中使用依赖项属性。很多人似乎不喜欢这样做,因为他们是wpf的一部分,并且具有线程关联性(您只能从创建特定对象的线程调用dependency属性方法) 我个人从未发现这是一个问题,因为您的视图既依赖于wpf,又具有线程关联性,因此即使使用了INotifyPropertyChanged,您仍然必须从正确的线程触发PropertyChanged事件 Dependecy属性具有内置的通知支持,不需要wpf进行任何反射,因此数据绑定速度更快(但设置/获取速度较慢,尽管时间尺度较小)
您的场景可能与我的场景有所不同,但我认为值得一看:)您可以使用.NET 4.5名为“CallerMemberName”的新功能来避免对属性名称进行硬编码。如果POCO将实现它们,它们将依赖于WPF。INotifyPropertyChanged与WPF无关。此外,POCO通常被用作模型。这些接口在视图模型上实现。所以你根本就不会选择这个模型。但我会更新我的第二个答案…关于第三个问题:
private string ExtractPropertyName<T>( Expression<Func<T>> propertyExpresssion )
{
if ( propertyExpresssion == null )
{
throw new ArgumentNullException( "propertyExpresssion" );
}
var memberExpression = propertyExpresssion.Body as MemberExpression;
if ( memberExpression == null )
{
throw new ArgumentException( "The expression is not a member access expression.", "propertyExpresssion" );
}
var property = memberExpression.Member as PropertyInfo;
if ( property == null )
{
throw new ArgumentException( "The member access expression does not access a property.", "propertyExpresssion" );
}
if ( !property.DeclaringType.IsAssignableFrom( this.GetType( ) ) )
{
throw new ArgumentException( "The referenced property belongs to a different type.", "propertyExpresssion" );
}
var getMethod = property.GetGetMethod( true );
if ( getMethod == null )
{
// this shouldn't happen - the expression would reject the property before reaching this far
throw new ArgumentException( "The referenced property does not have a get method.", "propertyExpresssion" );
}
if ( getMethod.IsStatic )
{
throw new ArgumentException( "The referenced property is a static property.", "propertyExpresssion" );
}
return memberExpression.Member.Name;
}
private string myProperty;
public string MyProperty
{
get
{
return myProperty;
}
set
{
myProperty = value;
this.RaisePropertyChanged( ( ) => MyProperty );
}
}
protected void RaisePropertyChanged<T>( Expression<Func<T>> propertyExpression )
{
var propertyName = ExtractPropertyName( propertyExpression );
this.RaisePropertyChanged( propertyName );
}