我看到很多类似的问题的答案说“使用DI容器注入你的模型”,但这并不能帮助我,所以我将提供一个小例子.
我们的应用程序是一个PeopleEditor.它用于加载和编辑People对象,这些对象很复杂.当您加载应用程序时,您会收到一个主屏幕,将一堆人员加载到内存中 – 让我们说,这些都可以通过我可以从我的容器获取的集合访问.通过点击一个人,你将被带到编辑器屏幕.编辑器很复杂,所以这不是一个屏幕中实现的一个简单的主 – 细节视图.
所以,在主屏幕上,当我点击一个人时,应用程序需要创建一个新的视图和viewmodel并显示视图.如果我先创建视图模型,通过容器,我可以使用适当的人物对象进行初始化.这对我来说似乎很自然,所以我很难想出为什么观看者似乎是主要的模式.我将如何使用第一种观点来实现?该视图将创建viewmodel,它可以获取People的集合,但不知道哪个人的编辑.编辑清楚:多人编辑可以一次存在,每个编辑一个不同的人.
Prism 4.0 alpha的MVVM参考实现使用“状态处理程序”,它基本上是应用程序用于在容器中存储构造函数参数的服务.它保存状态并调用ShowView,最终创建的viewmodel导入一个状态对象.这似乎对我来说很笨重 – 这就像是试图假装它真的不是偶然的.还有其他任何其他指导?
解决方法
我不是专家,但是我对于View-First和Model-First的了解是:
> View-First:查看程序viewmodel,创建视图,然后viewmodel自动创建.
> Model-First:viewmodel程序视图,在根应用程序中创建viewmodel对象图,将其分配给根视图数据上下文.然后让视图呈现其相关子项取决于视图模型.
不要说Model-First方法是坏的,但是我更喜欢View-First方法,因为viewmodel可以在后面的代码中,所以当一些进程需要非绑定友好的任务(PasswordBox,DialogConfirmation,ClosingForm等)时,我可以写我的代码背后的逻辑.
无论如何,为了解决这个情况,我通常使用IOC和Event Aggregator的组合.这里是:
>对于viewmodel,需要上下文信息在IOC容器中注册其实例,而不是其类型.所以它是一个准备就绪,甚至它的看法没有.
>当导航操作发生时(通过点击人员列表项),使用IOC容器解析器解析您的视图.并发送事件到具有指定参数的导航总线.此外,此事件将捕获目标viewmodel并执行某些操作.
注册viewmodel的实例并不是真的必要.只有当前一个viewmodel发送事件时,才能确保viewmodel准备就绪.
UPDATE
but then to populate it with any kind of local context I need to use a global facility to send it an event?
在您的情况下,上下文对象不是本地的,而是在对象调用之间传递的消息.显然,在你的第一种模式中,你可以做:
//selectedPeople is contextual object myPeopleDetailVM.LoadData(selectedPeople)
当您将selectedPeople传递给事件总线的参数时,它将几乎相同.
如果考虑性能,可以将其与WPF Routed Event System进行比较在这种情况下,路由策略比Event Bus更复杂,我认为如果您对使用WPF路由事件的信心比使用Event Aggregator更有信心.
我看到的唯一的问题是,如果你使用内置的框架事件聚合器(prism,mvvmlight),你的viewmodel被污染了事件总线,如果你抱怨这个,那么我同意你的意见.
希望有帮助