MVVM 模型应该是什么样的



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

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

谢谢。

这里有

3个答案:

  1. 您可以在 .NET 社区中找到引发 PropertyChanged 事件的替代方法,而无需将"PropName"作为字符串参数传递。但是,它们都有其他缺点(例如性能)。

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

  3. 不确定我是否正确理解了最后一个问题,但这里有一个答案。视图模型或数据模型应直接与模型交互。但是这些类不应以直接方式与视图交互。在此类场景中使用接口(例如 IView)。

可在此处找到详细信息:WPF 应用程序框架 (WAF)

  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 用作模型,接口由视图模型实现。

  3. 当您不包装 POCO 时,此问题已过时。

关于你的第一个问题:看看这篇文章

并进行谷歌搜索

有很多方法(和讨论)

我的2美分:

第一其次

还可以选择在视图模型中使用依赖项属性。很多人似乎不喜欢这样做,因为他们是 wpf 的一部分并且具有线程相关性(您只能从创建该特定对象的线程调用依赖项属性方法)

我个人从未发现这是一个问题,因为您的视图既依赖于 wpf 又具有线程亲和性,因此即使使用了 INotifyPropertyChanged,您仍然必须从正确的线程触发 PropertyChanged 事件。

依赖项属性具有内置的通知支持,并且不需要 wpf 执行任何反射,因此它们对于数据绑定速度更快(但设置/获取速度较慢,尽管时间尺度较小)

你的场景可能与我的不同,但我认为这是值得关注的:)

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

相关内容

  • 没有找到相关文章

最新更新