避免暴露于ViewModel的属性和事件的大规模传播

时间:2010-06-14 18:02:02

标签: .net wpf events architecture mvvm

我正在开发一个MVVM应用程序,我已准备好开始组建一个用户界面(我的客户端代码很大程度上是功能性的)

我现在遇到的问题是我正在尝试将我的应用程序数据提供给我需要的地方,以便它可以被视图模型使用然后绑定到视图。

不幸的是,似乎我要么得到一些结构性的疏忽,要么我将不得不面对我需要传播事件和引发过多错误以通知视图模型他们的属性的现实已经改变了。

让我谈谈我的问题的一些例子:

我有一个类“单元”包含在“Test”类中​​,包含在“TestManager”类中的“Session”类中,该类包含在“TestDataModel”中,“TestViewModel”使用该类,数据绑定到通过我的“TestView”...... WHOA。

现在,考虑到Unit(heiarchy的底部)有一个名为“Results”的属性,它会定期更新,我想将它暴露给我的viewmodel,然后将它数据绑定到我的视图,麻烦是,唯一的方法我我真的认为这样做是为了让事件永久化了一条链条,说“我已经更新了!”然后请求新的值...这似乎是一个很好的方式来做到这一点。或者,我可以注册静态事件并将其提升,并使用适当的“单元视图模型”获取事件并请求更新。这个SEEMS更好......但是......静态事件?这是一个禁忌的想法吗?

另外,有一个表达式:

TestDataModel.TestManager.Session.Test.Unit.Results[i] Seems REALLY gross to have on a View Model.  

我知道这一切都是一个糟糕的设计问题,但我无法弄清楚我做错了什么?我应该使用更多单例/容器控制的生命周期类型对象吗?使用静态帮助程序容器注册对象实例?也许是Multiton?显然,这些都是难以回答的问题而不是与现有结构密切相关,但如果你遇到这样的情况,你做了什么来重构?我是否应该忍受这种情况,添加群发事件并传播它们?

3 个答案:

答案 0 :(得分:4)

问题是你的TestView试图了解你的模型的一切。实际上,您希望拥有简单的视图并使用合成将它们组合成更复杂的视图。这样你就可以看到只处理单位而不处理其他内容的观点(其他观点会处理你的大模型的其他方面)这样你的viewmodels就会通过定义良好的API访问模型(例如获取单位等) 。)并且不需要通过暴露其所有内部构件来让任何人看到它来违反模型的封装。

答案 1 :(得分:0)

如果您的视图模型支持通知(例如,通过INotifyPropertyChanged),则视图中的常规数据绑定将意味着视图会自动更新。也许我在问题中遗漏了什么?

<强>更新

如果您关注属性链,那么您可以使用ResultsViewModel公开Results,然后将您的视图绑定到Results。结果应该是一个可观察的集合,每个Result应该实现INotifyPropertyChanged。我假设您的视图显示结果列表。

答案 2 :(得分:0)

您需要UI事件(不一定是INotifyPropertyChanged)来表示结果何时更新。如果要使用Prism,Prism包含一个事件聚合器,或者您可以通过在模型对象上使用自定义C#事件来获取它。

我不建议在模型对象上实现INotifyPropertyChanged;使用更具体的东西,例如

public event Action ResultsChanged

一旦设置了某种类型的事件系统,然后在ViewModel上,挂钩到Model事件并在每次结果更改时触发PropertyChanged事件。如果需要使数据绑定代码工作,请不要犹豫,创建更多ViewModel类(每个Result一个ViewModel)。