【问题标题】:Calculated columns should be where in MVVM model?计算列应该在 MVVM 模型中的哪个位置?
【发布时间】:2012-01-15 13:35:26
【问题描述】:

我有一个显示产品的 WPF DataGrid。我有两个字段 price 和 mass ,它们实际上是 Product 类的属性。我需要在网格名称 MultipliedValue = price * mass 中显示一个单独的列。根据 MVVM 模型,我应该在哪里做?

1) 在模型中通过创建只读属性。

2) 在转换器中,以便只有我的 UI 会意识到这一点?

3) 还是在视图模型中?

请建议我应该选择哪个选项以及为什么?

谢谢。

【问题讨论】:

    标签: mvvm


    【解决方案1】:

    我会从一开始就忽略选项#2——转换器应该只用于解释 UI 的实现细节,特别是在 MVVM 中可能甚至不会(因为你可以在 ViewModel 中进行转换,这是选项#3 更方便)。

    在 #1 和 #3 之间,在这种情况下,恕我直言,最好使用 #1 - 价格不仅仅是与您的 UI 相关的东西,当然价格的概念(以及它的派生方式)将在整个应用程序中保持固定。 UI 和您的后端都可以选择使用或不使用此属性。

    【讨论】:

      【解决方案2】:

      我会以不同的方式争论(与@jon 不同)。我只在模型中放入了我想序列化的属性(例如,来自服务器)。计算属性不会序列化,因此它们不在模型中。

      最近,我最喜欢的 Model/View Model 范例如下: Product 是 Model 中的一个类,除了最简单的 getter 和 setter 之外什么都没有。 ProductVm 是 VM 中的一个类,它包含 Product,并具有附加的 VM 逻辑。最重要的是,属性更改通知 - 我认为这也是 VM 的一部分,而不是模型。

      // Model:
      class Product {
          public double Price { get; set; }
          public double Mass { get; set; }
      }
      
      // View Model:
      class ProductVM : INotifyPropertyChanged
      {
          Product _product;
          public event PropertyChangedEventHandler PropertyChanged;
      
          public double Price {
              get { return _product.Price; }
              set { _product.Price = value; raise("Price"); raise("Total"); }
          }
      
          public double Mass {
              get { return _product.Mass; }
              set { _product.Mass = value; raise("Mass"); raise("Total"); }
          }
      
          public double total {
              get { return Price * Mass; }
          }
      
          private void raise(string name) {
              if( PropertyChanged ) {
                  PropertyChanged( this, new PropertyChangedEventArgs(name) );
              }
          }
      
          public ProductVm( Product p ) {
              _product = p;
          }
      
          public ProductVm() {
              // in case you need this
              _product = new Product();
          }
      }
      

      是的,这里有很多样板,但是一旦你完成了所有的输入,你会发现 Model 和 ViewModel 之间的这种分离非常有用。我的 2 美分。

      注意:我认为@Jon 的方法也是正确的,并且理由是有效的。我认为没有一个答案。

      【讨论】:

      • 通过使用您的设计,在模型中定义的属性将主要在视图模型中重新定义。此外,您在 ViewModel 中定义了业务规则,但没有在 Model 中定义。这似乎与 MVVM 模式相矛盾。不过,您的设计似乎也很有趣。
      • 我不同意这种设计。您已将业务逻辑(Total 字段)放入作为应用程序层一部分的视图模型中。另外,我不明白您为什么不在模型上实现 INotifyPropertyChanged,因为它使一切变得容易得多。
      • 谢谢@HosseinShahdoost。我将解释:关于 INotifyPropertyChanged 不在模式中:这很容易。我们希望保持模型尽可能干净和独立。例如 - 模型是我们序列化以通过网络发送的。它应该始终只包含数据,并且可能(每种方式都有很大的论据)数据的验证逻辑。至于Total字段,我会问你:MVVM应用中的应用层是什么?是这样的景色吗?那是模型吗(再说一遍,你会序列化 Total)吗?
      • 我也不同意大型模型,但是仅数据模型(更像是旧结构)也是一种不好的做法。序列化实现了 INotifyPropertyChanged 的​​模型没有任何问题,并且在序列化过程中也可以省略 Total 字段,因此不会有问题。但是,如果您想在网格上显示模型(特别是总计字段)怎么办?由于那里没有总计。
      • 关于应用层。我建议你看看这个msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx,业务逻辑最好在 ViewModel 之外处理。 ViewModel 必须只做 PresentationLogic,例如本地化,......而不是业务和数据逻辑
      猜你喜欢
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-18
      相关资源
      最近更新 更多