计算列应该在MVVM模型中的何处?

计算列应该在MVVM模型中的何处?,mvvm,Mvvm,我有一个WPF数据网格显示产品。我有两个字段price和mass,它们实际上是产品类的属性。我需要在网格名称multipledvalue=price*mass中显示一个单独的列。根据MVVM模型,我应该在哪里做 1) 在模型中创建只读属性 2) 在转换器中,这样只有我的UI才会知道 3) 还是在视图模型中 请建议我应该选择哪个选项,为什么 谢谢。我会从一开始就忽略选项2——转换器应该只用于说明UI的实现细节,特别是在MVVM中,甚至在MVVM中可能也不会(因为您可以在ViewModel中进行转换

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

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

2) 在转换器中,这样只有我的UI才会知道

3) 还是在视图模型中

请建议我应该选择哪个选项,为什么

谢谢。

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

在#1和#3之间,在本例中,我认为最好使用#1——价格不仅仅与您的UI相关,当然,价格的概念(以及它是如何派生的)将在整个应用程序中保持不变。UI和后端都可以选择使用或不使用此属性。

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

在#1和#3之间,在本例中,我认为最好使用#1——价格不仅仅与您的UI相关,当然,价格的概念(以及它是如何派生的)将在整个应用程序中保持不变。用户界面和后端都可以选择使用或不使用此属性。

我的观点与@jon不同。我只将要序列化的属性(例如,从服务器)放入模型中。计算属性不会序列化,因此它们不在模型中

// 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();
    }
}
最近,我最喜欢的模型/视图模型范例如下:产品是模型中的一个类,它只有最简单的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();
    }
}
是的,这里有很多样板文件,但是一旦你完成了所有的输入,你会发现模型和视图模型之间的这种分离非常有用。我的2美分

注:我认为@Jon方法也是正确的,原因也是有效的。我不认为有一个答案。

我的观点与@jon不同。我只将要序列化的属性(例如,从服务器)放入模型中。计算属性不会序列化,因此它们不在模型中

// 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();
    }
}
最近,我最喜欢的模型/视图模型范例如下:产品是模型中的一个类,它只有最简单的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();
    }
}
是的,这里有很多样板文件,但是一旦你完成了所有的输入,你会发现模型和视图模型之间的这种分离非常有用。我的2美分


注:我认为@Jon方法也是正确的,原因也是有效的。我认为没有一个答案。

通过使用您的设计,模型中定义的属性将在ViewModel中重新定义。此外,您在ViewModel中定义了业务规则,但在ViewModel中没有定义。这似乎与MVVM模式相矛盾。然而,你的设计似乎也很有趣。我不同意这种设计。您已经将业务逻辑(Total字段)放在作为应用层一部分的视图模型中。另外,我不明白你为什么不在模型上实现INotifyPropertyChanged,因为它让一切都变得容易多了。谢谢@HosseinShahdoost。我将解释:关于INotifyPropertyChanged不在模式中:这很容易。我们希望尽可能保持模型的干净性和独立性。例如,模型是我们序列化后通过网络发送的。它应该总是只包含数据,并且可能(每种方式都有很大的争论)数据的验证逻辑。至于Total字段,我将问您:MVVM应用程序中的应用程序层是什么?是这样吗?这就是模型吗(那么,你会把总数序列化吗)?我也不同意大模型,但只使用数据模型(更像是旧结构)也是一种不好的做法。序列化实现INotifyPropertyChanged的模型没有什么错,并且在序列化过程中也可以省略Total字段,所以这不会是一个问题。但是,如果要在网格上显示模型(特别是总字段),该怎么办?因为那里没有总数。关于应用层。我建议您看看这个,业务逻辑最好在ViewModel之外处理。ViewModel只能执行PresentationLogic,例如本地化。。。而不是业务和数据逻辑通过使用您的设计,在模型中定义的属性将主要在ViewModel中重新定义。此外,您在ViewModel中定义了业务规则,但在ViewModel中没有定义。这似乎与MVVM模式相矛盾。然而,你的设计似乎也很有趣。我不同意这种设计。您已经将业务逻辑(Total字段)放在作为应用层一部分的视图模型中。另外,我不明白你为什么不在模型上实现INotifyPropertyChanged,因为它让一切都变得容易多了。谢谢@HosseinShahdoost。我将解释:关于INotifyPropertyChanged不在模式中:这很容易。我们希望尽可能保持模型的干净性和独立性。例如,模型是我们序列化后通过网络发送的。它应该总是只包含数据,并且可能(每种方式都有很大的争论)数据的验证逻辑。至于总场,我会问你:什么