【问题标题】:What should MVVM Model be like?MVVM 模型应该是什么样的?
【发布时间】:2011-05-13 08:33:55
【问题描述】:

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

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

谢谢。

【问题讨论】:

    标签: mvvm model poco inotifypropertychanged idataerrorinfo


    【解决方案1】:

    这里有 3 个答案:

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

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

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

    更多信息可以在这里找到:WPF Application Framework (WAF)

    【讨论】:

    • 关于第三个问题:link
    【解决方案2】:
    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 时,此问题已过时。

    【讨论】:

    • 如果 POCO 将实现它们,它们将依赖于 WPF。
    • INotifyPropertyChanged 与 WPF 无关。除此之外,通常使用 POCO 作为模型。接口在视图模型上实现。所以你根本不会碰模型。但我会更新我的第二个答案...
    【解决方案3】:

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

    还有do a google search

    有很多方法(和讨论)

    我的 2 美分:

    First 还有second

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-12-03
          • 2015-03-20
          • 1970-01-01
          • 2012-12-23
          • 1970-01-01
          • 2012-01-05
          • 2013-10-31
          相关资源
          最近更新 更多