【问题标题】:What is the ideal way to define property changes from a Model to a View in MVVM?在 MVVM 中定义从模型到视图的属性更改的理想方法是什么?
【发布时间】:2016-10-04 20:49:16
【问题描述】:

我正在尝试重构 MVVM 架构中的一些代码。
该模型具有直接更改的公共值。

UI 监听这些值的变化。

下面是事件信号代码:

public string LoadFilename   { get { return _loadFilename;   } set { _loadFilename   = value; OnPropertyChanged(); } }
public string SaveFilename   { get { return _saveFilename;   } set { _saveFilename   = value; OnPropertyChanged(); } }
public string OneSafFilename { get { return _oneSafFilename; } set { _oneSafFilename = value; OnPropertyChanged(); } }

public bool IsSaveEnabled           { get { return _isSaveEnabled;           } set { _isSaveEnabled           = value; OnPropertyChanged(); } }
public bool IsLoadEnabled           { get { return _isLoadEnabled;           } set { _isLoadEnabled           = value; OnPropertyChanged(); } }
public bool IsLoadCheckpointEnabled { get { return _isLoadCheckpointEnabled; } set { _isLoadCheckpointEnabled = value; OnPropertyChanged(); } }
public bool IsCheckpointEnabled     { get { return _isCheckpointEnabled;     } set { _isCheckpointEnabled     = value; OnPropertyChanged(); } }
public bool IsScenariosEnabled      { get { return _isScenariosEnabled;      } set { _isScenariosEnabled      = value; OnPropertyChanged(); } }

这里是OnPropertyChanged函数:

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

这似乎是 MVVM 中应该很自然的东西的大量样板。
我想让它更简洁,但我不知道从哪里开始。

通过监听上述属性的视图,getter 和 setter 应该是什么样的?

【问题讨论】:

  • 我完全同意@HenkHolterman,您可以将 INPC 实现移到基类中。这是我之前使用过的一个小例子stackoverflow.com/questions/33801100/…
  • 首先,不要忘记减少 derp 的语言特性 (PropertyChanged?.Invoke(...)) 其次,有很多方法可以改善这种情况,从 T4 模板生成样板,使用类型描述符,包装您在 IDynamicMetaObjectProviders 等中的 POCO。

标签: c# wpf mvvm inotifypropertychanged field-accessors


【解决方案1】:

实现 INPC 始终是 WPF/XAML 中丑陋的部分。有了一个好的基类,它可以减少到{ get { return _loadFilename; } set { Set(ref _loadFilename, value); } },但这几乎和它一样紧凑。 Resharper 支持(重构)这个。

顺便说一句,您的代码也缺少优化保护 if(value != _loadFilename) 。所以BindableBase 基类绝对是个好主意。

【讨论】:

    【解决方案2】:

    您可能想研究Fody's PropertyChanged 之类的东西,它会在构建时重写 IL 以注入更改通知代码。

    【讨论】:

      【解决方案3】:
      private type m_name;
          public type name
          {
              get { return m_name; }
              set
              {
                  m_name = value;
                  if (PropertyChanged != null)
                  { PropertyChanged(this, new PropertyChangedEventArgs("name")); }
              }
          }
      

      我将上述代码用于需要侦听器的属性更改。 type 是属性的类型,name 是属性的名称(在代码中的任何位置更改“类型”和“名称”)

      有关 MVVM 的精彩教程,它解释了有关属性更改和代码 sn-ps 的更多信息,请查看 YouTube 上的 Jerry Nixon:https://www.youtube.com/watch?v=cB7KdYPQw1k 它有点过时了,但仍然很有帮助!

      【讨论】:

      • 在引号中使用“名称”是原始代码的一大退步。这也更长。 OnPropertyChange() 方法属于推荐模式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 2012-03-12
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 2013-03-10
      相关资源
      最近更新 更多