在setter中自我订阅PropertyChanged或添加方法调用?

cho*_*dze 8 c# wpf mvvm inotifypropertychanged

也许这里已经是这样的问题,但我没有找到它.

我有MVVM应用程序,并且ViewModel我必须对某些属性的更改执行一些其他操作(例如,如果View更改它们).哪种方法更好,为什么?

1st - 添加AdditionalAction对setter的调用

public class ViewModel: INotifyPropertyChanged
{
  private int _MyProperty;

  public int MyProperty
  {
    get { return _MyProperty; }
    set
    {
      if (_MyProperty == value) return;
      _MyProperty = value;
      RaisePropertyChanged(() => MyProperty);

      // --- ADDITIONAL CODE ---
      AdditionalAction();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

第二 - 自我订阅INotifyPropertyChanged

public class ViewModel: INotifyPropertyChanged
{
  public ViewModel()
  {
    // --- ADDITIONAL CODE ---
    PropertyChanged += OnPropertyChanged;
  }

  private int _MyProperty;

  public int MyProperty
  {
    get { return _MyProperty; }
    set
    {
      if (_MyProperty == value) return;
      _MyProperty = value;
      RaisePropertyChanged(() => MyProperty);
    }
  }

  void PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
    // --- ADDITIONAL CODE ---
    if (e.PropertyName == "MyProperty")
      AdditionalAction();
  }
}
Run Code Online (Sandbox Code Playgroud)

想象一下,我没有性能问题或10'000个对象.它只是View和ViewModel.什么是更好的?第一个代码是"更小"并且开销更少,但第二个(在我看来)更清晰,我可以使用代码片段来自动生成属性的代码.更多 - 在第二种情况下,我可以在事件处理程序中写入类似于:

On.PropertyChanged(e, p => p.MyProperty, AdditionalAction);
Run Code Online (Sandbox Code Playgroud)

哪个On是类助手.

那么,你的想法更好,为什么?

更新:

好吧,看起来我发现了一种方法:

3 - 在RaisePropertyChanged中添加"扩展点":

public class NotificationObject : INotifyPropertyChanged
{
  void RaisePropertyChanged(Expression<...> property)
  {
    // ... Raise PropertyChanged event
    if (PropertyChanged != null)
      // blah-blah

    // Call extension point
    OnPropertyChanged(property.Name);
  }

  public virtual OnPropertyChanged(string propertyName)
  {
  }
}

public class ViewModel: NotificationObject
{
  private int _MyProperty;

  public int MyProperty
  {
    get { return _MyProperty; }
    set
    {
      if (_MyProperty == value) return;
      _MyProperty = value;
      RaisePropertyChanged(() => MyProperty);
    }
  }

  override OnPropertyChanged(string propertyName)
  {
    if (propertyName == "MyProperty")
      AdditionalAction();
  }
}
Run Code Online (Sandbox Code Playgroud)

这样我们就不会使用事件,而是从同一个"扩展点"调用所有"附加操作"."不透明的工作流程"比"不是透明的工作流程"更好吗?

Tig*_*ran 3

肯定会选择第一种方法:

  • 天气晴朗
  • 它的流程和意图很明确
  • 它避免了奇怪的(我认为)自我订阅

在我看来,第二个允许您使用自动生成的属性的“好处”不值得第一个案例的执行流程的清晰性。

希望这可以帮助。