1

我的问题是“最佳实践是什么?” 类型,在一个非常具体的情况下:

我有一个包含复选框列表框的视图。

listbox.ItemsSource绑定到ViewModel(人员列表)中的集合。每个checkbox.IsChecked都绑定到Person.IsSelected

复选框的选中/取消选中会激活 ViewModel 中的“刷新”方法,该方法可能会或可能不会重新设置所有人员的 Person.IsChecked。当然,这应该通知 UI Person.IsChecked(可能已经)已更改。

我的问题是:谁应该负责调用ViewMode.Refresh?UI 是否应该通过事件或命令调用该方法?或者ViewModel是否应该订阅Person中的适当事件。

4

4 回答 4

3

如果 UI 绑定到IsChecked,则无需通知它。或者,更确切地说,WPF 本身会通知它。这是 MVVM 的吸引力之一。视图模型可以根据自己的一组规则简单地更新其状态,并且视图会通过绑定自动接收这些更改。

于 2013-09-13T11:58:25.813 回答
1

我想你要问自己,“刷新”是什么反应?

如果它响应物理上被单击的复选框,那么调用它是视图的责任。

如果它是对被选中的人的响应,则视图模型应该监视它自己的集合以了解对 IsSelected 的更改。

我同意MehaJain的观点,后者更难设置,但替代方案打破了层之间单个工作单元的责任,这意味着逻辑将需要在导致 IsSelected 更改的任何其他函数中复制。这包括绑定到相同信息的其他视图、其他命令(例如,您有一个用于运行选择某些人的过滤器的按钮)和测试。

于 2013-09-13T14:34:22.940 回答
1

取决于您所说的“呼叫”是什么意思

这是答案

如果您的意思是创建:

  • 其他视图模型
  • 任何不是视图或模型的东西(因为它们都不应该知道你的虚拟机)

如果您谈论执行方法:

  • 自执行(例如在 PropertyChanged、Command、...之后)
  • 其他视图模型
  • 任何不是视图或模型的东西(因为它们都不应该知道你的虚拟机)

在您的情况下也很重要:

你说你的列表绑定到集合
,在这里你可能会遇到一些麻烦,因为你的视图改变了Person.IsSelected应该为你的 IsSelected 引发一个 PropertyChanged。
现在它会卡住,因为如果您的 Item Property Changed这是一个已知问题,则ObservableCollection不会收到通知。要解决此问题,您需要将您的事件连接到您的. 所以它可以冒泡到你的虚拟机,它可以执行他的INotifyPropertyChangedCollectionChangedObservableCollectionRefresh()

在这里,您可以看到一个示例,您可以如何做到这一点。

于 2013-09-13T14:04:56.737 回答
0

我更愿意通过事件或命令来刷新视图模型。

因为订阅集合成员很棘手。假设您想使用第二种方法:订阅 Person 类更改事件。那么它可能有以下缺点:

  • 在视图模型的构造函数中,您必须订阅列表中的每个“Person”成员。
  • 在视图模型中,每当集合被修改时,您必须订阅/取消订阅该列表中添加/删除的成员。
  • 在处理您的视图模型时,您必须取消订阅已订阅的更改事件。

因此,如果您要订阅 Person 类的更改事件,这是一个开销。

于 2013-09-13T13:46:32.980 回答