您好我有关于MVVM模型的3个问题。
PropertyChanged("PropName");
INotifyPropertyChanged, IDataErrorInfo
感谢。
答案 0 :(得分:3)
以下是3个答案:
您可以找到提升PropertyChanged事件的替代方法,而不会在.NET community中将“PropName”作为字符串参数传递。但是,它们都有其他缺点(例如性能)。
最好的方法是直接在Model中实现INotifyPropertyChanged和IDataErrorInfo。这并不总是可行的。如果你需要包装模型类,那么你可以查看DataModel概念。
我不确定我是否理解了最后一个问题,但这是一个答案。 ViewModel或DataModel应直接与Model交互。但是这些类不应该直接与View交互。对这种情况使用接口(例如IView)。
可在此处找到更多信息: WPF Application Framework (WAF)
答案 1 :(得分:1)
是的,您可以使用Lamdba表达式执行此操作。但这会耗费一些处理器时间(进行一些快速测量:这种方法比使用字符串常量慢大约200倍。在高频率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 );
}
我认为你不必包装它们(除了创建一个相应的视图模型)。 POCO用作模型,接口由viewmodel实现。
答案 2 :(得分:0)
答案 3 :(得分:0)
还可以在viewmodel中使用Dependency属性。很多人似乎不喜欢这样做因为它们是wpf的一部分并且具有线程亲和性(你只能从创建该特定对象的线程中调用依赖属性方法
我个人从未发现这是一个问题,因为你的视图既依赖于wpf又具有线程亲和性,所以即使使用了INotifyPropertyChanged,你仍然需要从正确的线程中激活PropertyChanged事件。 / p>
Dependecy属性内置了通知支持,并且不需要wpf进行任何反射,因此它们对数据绑定更快(但在较小的时间范围内设置/获取速度较慢)
你的情景可能与我的情况有所不同,但我认为看起来很有意思:)
答案 4 :(得分:0)
您可以使用名为“CallerMemberName”的.NET 4.5新功能来避免对属性名称进行硬编码。