如何实现包装模型属性的视图模型

时间:2017-05-18 13:22:40

标签: c# wpf mvvm

假设一个名为Value的属性附带的模型。该模型实现了INotifyPropertyChanged。接下来,假设一个知道模型的视图模型,并为虚构视图提供属性Value。该视图模型实现如下:

查看模型代码段

public int Value
{
    get {
        Model.Value;
    }
    set {
        if(value != Model.Value) {
            Model.Value = value;
            OnPropertyChanged();
        }
    }
}

即。此时视图的整个目的是直接将模型的属性传递给视图。

视图模型已注册到模型的PropertyChanged事件中。每次Value模型更改时,视图模型都会注意到更改并触发PropertyChanged事件本身,以便绑定到视图模型的属性Value的视图知道更新自己。

这导致多个PropertyChanged调用如果通过视图模型更改模型:

  1. 进入视图模型的代码后,在执行Model.Value = value;
  2. 后侦听模型的更改
  3. 由于Value
  4. 而再次出现在OnPropertyChanged();的设定者中

    我想到的唯一解决方案是将视图模型与模型完全分开。这包括保留模型数据的完整克隆。这样我可以避免第一次调用PropertyChanged。因为我能够将视图模型的值与模型的值进行比较,所以我可以区分不同的更改源(即视图模型更改的模型或模型已被其他源更改)。

    请注意,视图模型要复杂得多。将模型与视图模型合并不是解决方案。

2 个答案:

答案 0 :(得分:1)

如果视图模型已注册到模型的属性已更改,并反过来引发其自身的属性更改,则视图模型的属性中不需要OnPropertyChanged()

删除OnPropertyChanged()

ViewModel代码看起来像。

public int Value {
    get {
        return Model.Value;
    }
    set {
        if(value != Model.Value) {
            Model.Value = value;
        }
    }
}

答案 1 :(得分:1)

viewmodel应该负责更新视图和更新模型。

您已经基本确定了该模型不应该实施INotifyPropertyChanged的原因,并且不应该做任何需要它的事情。没有一种干净,正常的MVVM方式来做你正在尝试做的事情。这表明你做错了MVVM。当然,MVVM并不是神圣的,但它确实运作良好,而你所做的事情已经让你陷入困境。您已经创建了一个您不需要创建的问题,并且没有很好的解决方案。答案不是选择最差的解决方案;它回过头来消除设计中的问题。

这种设计从根本上构思错误,任何通过增加复杂性来挽救它的企图都将是一团糟。值得做的是因为你从中吸取了教训,但是不值得再花时间投入。

您的文字问题的答案,"如何实现包装模型的属性"的viewmodel [property],是:

就像您在public int Value示例中所做的那样,但没有实施INotifyPropertyChanged的模型。