繁体   English   中英

属性设置器是否可以使用MVVM模式产生副作用

[英]Is it OK for property setters to have side effects with the MVVM pattern

我正在编写旨在解决标准问题的WPF应用程序。 我是WPF和MVVM模式的新手,所以在网上阅读了大量不同的MVVM方法后,我的脑子里有点乱。 我想知道DataGrid的itemsource刷新操作的简单操作对于MVVM来说是“惯用的”。

假设我有一个数据网格和一个组合框。 组合包含所有教练的列表。 数据网格显示由所选教练训练的所有运动员,因此组合就像数据网格中数据的过滤器:

<ComboBox ItemsSource="{Binding ListCoach}" DisplayMemberPath="last_name" SelectedValue=
"{Binding SelectedCoach}" SelectedValuePath="Id"/>

<DataGrid ItemsSource="{Binding Path=ListSportsman}" .....  </DataGrid>

我的ViewModel类在SelectedCoach属性的setter中更改DataGrid的内容(此属性是Combobox值的目标):

  private int _selectedCoach;
  public int SelectedCoach
  {
     get { return _selectedCoach; }
     set
     {
        _selectedCoach = value;
        ListSportsman = new ObservableCollection<sportsmanset>(_serviceAgent.ListSportsmanOfCoach(value));
        NotifyPropertyChanged(vm => vm.SelectedCoach);
     }
  }

这样的代码闻不到吗? 或者,在SelectedCoach属性中订阅更改并在单独的函数中设置ListSportsman更合适? (顺便说一句,如何手动订阅NotifyPropertyChanged事件?)

根据定义,这没有错,但有一点需要考虑:

一般来说,开发人员希望setter和getters能够快速完成。 因此,如果要添加需要花费大量时间的逻辑,则可能需要异步执行该逻辑或使用Set方法替换该属性,因此很明显存在涉及的处理。

部分处理可能是设置View可以绑定的属性。

不,这段代码没有'闻到'!

视图模型与它“后退”的视图密切相关。 在您描述的视图中,这两个属性非常紧密耦合,因此它们在视图模型中紧密耦合是有意义的。

另外,只要问问自己,拥有逻辑,填充数据网格,通过事件处理松散耦合会带来什么好处? 这可以让您更容易地执行此逻辑作为其他事件的结果,或者可能分成两个类,以便在代码中的其他位置重用。 这些情况中是否有可能出现? 如果没有,让你的代码无缘无故变得更复杂就是代码味道本身!

顺便说一下,如果你想手动处理这个,你需要向类PropertyChanged事件添加一个事件处理程序。

我的回答是“不,不行”。 对于简单的应用程序/原型,它很好,但是对于更高级的场景或养成良好的习惯/设置示例 - 它不是。

该怎么做? 没有“一个尺寸适合所有答案”但我建议根据我的经验:

  1. 始终保持setter哑,即只设置值和NotifyPropertyChanged。
  2. 尝试将昂贵的业务逻辑和其他副作用封装在命令中。 如果它不可能并且必须由setter触发,则从PropertyChanged创建可观察的Rx流并订阅它。 这可能听起来有点矫枉过正,但Rx对MVVM的好处是巨大的。 这是一种可能的(不是最好的)方法: http//blog.leifbattermann.de/2015/06/21/viewmodel-property-to-observable-stream/
  3. (offtopic但不是真的)也不会引起setter中简单依赖只读属性的更改,而是使用https://github.com/StephenCleary/CalculatedProperties或类似(我怀疑此刻有什么更好的)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM