MVVM模型应该是什么样的?

时间:2011-05-13 08:33:55

标签: mvvm model poco inotifypropertychanged idataerrorinfo

您好我有关于MVVM模型的3个问题。

  1. 没有办法绕过多余的PropertyChanged("PropName");
  2. 将POCO对象包装到WPF INotifyPropertyChanged, IDataErrorInfo
  3. 的最佳方法是什么
  4. 我应该如何与ViewModel中的(WPfWrapers-POCO)进行交互 - 通过强制转换或属性......
  5. 感谢。

5 个答案:

答案 0 :(得分:3)

以下是3个答案:

  1. 您可以找到提升PropertyChanged事件的替代方法,而不会在.NET community中将“PropName”作为字符串参数传递。但是,它们都有其他缺点(例如性能)。

  2. 最好的方法是直接在Model中实现INotifyPropertyChanged和IDataErrorInfo。这并不总是可行的。如果你需要包装模型类,那么你可以查看DataModel概念。

  3. 我不确定我是否理解了最后一个问题,但这是一个答案。 ViewModel或DataModel应直接与Model交互。但是这些类不应该直接与View交互。对这种情况使用接口(例如IView)。

  4. 可在此处找到更多信息: WPF Application Framework (WAF)

答案 1 :(得分: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 );
    }
    
  2. 我认为你不必包装它们(除了创建一个相应的视图模型)。 POCO用作模型,接口由viewmodel实现。

  3. 如果不包装POCO,这个问题已经过时了。

答案 2 :(得分:0)

关于你的第一个问题: 有一个look at this post

do a google search

有很多方法(和讨论)

我的2美分:

Firstsecond

答案 3 :(得分:0)

还可以在viewmodel中使用Dependency属性。很多人似乎不喜欢这样做因为它们是wpf的一部分并且具有线程亲和性(你只能从创建该特定对象的线程中调用依赖属性方法

我个人从未发现这是一个问题,因为你的视图既依赖于wpf又具有线程亲和性,所以即使使用了INotifyPropertyChanged,你仍然需要从正确的线程中激活PropertyChanged事件。 / p>

Dependecy属性内置了通知支持,并且不需要wpf进行任何反射,因此它们对数据绑定更快(但在较小的时间范围内设置/获取速度较慢)

你的情景可能与我的情况有所不同,但我认为看起来很有意思:)

答案 4 :(得分:0)

您可以使用名为“CallerMemberName”的.NET 4.5新功能来避免对属性名称进行硬编码。