2

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

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

谢谢。

4

5 回答 5

3

这里有3个答案:

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

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

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

可以在此处找到更多信息:WPF 应用程序框架 (WAF)

于 2011-05-13T17:19:34.317 回答
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 用作模型,接口由视图模型实现。

  3. 当您不包装 POCO 时,此问题已过时。
于 2011-05-13T09:03:35.463 回答
0

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

进行谷歌搜索

有很多方法(和讨论)

我的 2 美分:

第一第二

于 2011-05-13T09:09:42.577 回答
0

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

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

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

您的情况可能与我的情况不同,但我认为它看起来很有趣:)

于 2011-05-16T11:39:25.043 回答
0

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

于 2013-09-12T02:10:46.890 回答