我有一些逻辑取决于设置的两个属性,因为这两个属性都有值时才执行。例如:

private void DoCalc() {
  if (string.IsNullOrEmpty(Property1) || string.IsNullOrEmpty(Property2))
    return;
  Property3 = Property1 + " " + Property2;
}

每当Property1或Property2更改时,都需要执行该代码,但是我在弄清楚如何以样式上可接受的方式进行处理时遇到了麻烦。我看到的是以下选择:

1)从ViewModel调用方法

从概念上讲,我对此没有问题,因为逻辑仍然存在于ViewModel中-我不​​是“没有代码隐藏”的纳粹。但是,“触发”逻辑(当两个属性均发生更改时)仍在UI层中,我并不喜欢。后面的代码如下所示:
void ComboBox_Property1_SelectedItemChanged(object sender, RoutedEventArgs e) {
  viewModel.DoCalc();
}

2)从属性 setter 调用方法

这种方法似乎是最“纯粹”的,但也似乎很难看,好像逻辑是隐藏的。它看起来像这样:
public string Property1 {
  get {return property1;}
  set {
    if (property1 != value) {
      property1 = value;
      NotifyPropertyChanged("Property1");
      DoCalc();
    }
  }
}

3)插入PropertyChanged事件

我现在正在考虑这可能是正确的方法,但是在实现 View 模型中挂入属性更改事件感觉很奇怪。它看起来像这样:
public ViewModel() {
  this.PropertyChanged += new PropertyChangedEventHandler(ViewModel_PropertyChanged);
}

void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) {
  if (e.PropertyName == "Property1" || e.PropertyName == "Property2") {
    DoCalc();
  }
}

因此,我的问题是,如果您正在浏览具有该要求的某些源代码,那么您更希望看到哪种方法已实现(为什么?)。感谢您的任何投入。

最佳答案

我认为在setter中执行此操作并不难看...实际上,这可能是您提到的3种方法中的最佳方法,因为当您阅读代码时,您会立即看到更改Property1Property2的值将重新计算Property3;对于其他两种方法,这一点都不明显。

但是,我不会使用这些选项。我认为一种更好的方法是根据Property3Property1Property2设为只读,并在getter中计算其值:

public string Property3
{
    get { return Property3 = Property1 + " " + Property2; }
}

这样,在Property1Property2的 setter 中,您只需要为NotifyPropertyChanged调用Property3

10-01 17:54