【问题标题】:How do View Models propagate change notification from their underlying Models if the Model do not implement INotifyPropertyChanged?如果模型不实现 INotifyPropertyChanged,视图模型如何从其底层模型传播更改通知?
【发布时间】:2011-10-02 05:22:06
【问题描述】:

阅读Josh Smiths article about MVVM 他的视图模型CustomerViewModel 实现INotifyPropertyChanged 但不是底层Customer 类。

在这种情况下,我只能看到一种(可行的)方法来使更改通知起作用 - 仅更改 CustomerViewModel 而不是 Customer。在那种情况下,我的程序的后端逻辑是否也应该简单地针对 ViewModel 工作?这看起来很奇怪,毕竟它们是 View 模型。

谁能解释一下?

谢谢!

澄清:

假设我有一个模型引用和一个引用列表。

public class Quote
{
    public string Name { get; set; }
    public decimal Value { get; set; }
}

public QuoteViewModel : INotifyPropertyChanged
{
    private Quote quote;

    public event EventHandler PropertyChanged;

    public decimal Value 
    { 
         get { return quote.Value; }
         set
         { 
               quote.Value = value;
               PropertyChanged("Value");
         }
    }                  
}

现在,如果 Quote 因后台线程轮询 Web 服务而发生变化,UI 将不会收到通知,因为 Quote 没有实现 INotifyPropertyChanged,除非系统的所有部分都使用 ViewModel?

【问题讨论】:

    标签: c# .net wpf mvvm


    【解决方案1】:

    我猜在他的示例中,他正在使用通知将视图的 one 部分的更改传播到视图的 其他 部分。由于不同的部分大概绑定到同一个视图模型,这会起作用。

    重新逻辑验证;无论如何,我可能不会基于更改事件。首先是因为这将是一个 lot 的偶数订阅(对比 UI,您只绑定 UI 关心 关心的东西),其次它可能太重要了,不能冒丢失的风险; p 如果模型没有在内部执行验证(随着更改发生),那么我将在提交之前显式运行验证逻辑,同时查看成员。这也避免了“短暂不一致”的问题,即您计划进行几处更改,导致在一个有效的模型中,但如果你验证立即,要么真的很尴尬找到一个序列,让你做出你想要的改变,或者是完全不可能的。通过推迟验证,这种情况就会消失。

    【讨论】:

    • 谢谢,我同意你的说法,但我不确定它如何适用于我刚刚澄清我的问题的案例。请看一下并为我澄清! :)
    • @Max - 更新绑定到 UI 的对象的后台线程已经是一个非常狡猾的场景,因为仅仅处理事件是不够的 - 它需要进行线程切换等。确实,它无法处理这种情况,但问题是:模型需要设计为仅处理它们将实际遇到的事情。大多数模型不需要处理您呈现的场景。如果您的模型确实需要它,那么它需要以更复杂的方式进行设计(和测试)。但是除非你需要它,否则你不会添加它;p
    • 好吧,我认为模型不应该知道它是否绑定到 UI - 我认为 ViewModel 在收到此类通知时在正确的线程上编组/调用更改是非常合理的由模型。但是,模型以与视图不直接相关的方式发生变化的情况并非罕见?
    • @max 也许 - 短版;这取决于您,但实际上所描述的模型不会那样工作
    【解决方案2】:

    Marc 提出了一些很好的观点,但听起来您确实需要在 UI 上下文之外修改模型。考虑在您的模型上实现 INotifyPropertyChanged,但正如 Marc 所提到的,这可能会有点问题,并且肯定需要进行大量测试。如果您的模型是 POCO,这种方法效果最好。如果它可以兼作在所有使用它的 VM 中公开的伪 VM,那么也许您可以最小化或消除 VM->模型事件订阅:

    public QuoteViewModel : INotifyPropertyChanged
    {
      private Quote quote;
      public event EventHandler PropertyChanged;
      public INotifyPropertyChanged Quote
      {
        get { return quote; }
        set
        {
          quote = value;
          PropertyChanged("Quote");
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多