日期:2014-05-17  浏览次数:21042 次

WPF MVVM模式下,在ViewModel层业务逻辑处理完毕之后,如何打开关闭窗体
有一种不太规范的方式,利用CommandParameter传递Window对象。

<i:Interaction.Triggers>
<i:EventTrigger>
<i:InvokeCommandAction Command="{Binding GetWindow}" CommandParameter="{Binding ElementName=window}"/>
</i:EventTrigger>
</i:Interaction.Triggers>

在GetWindow的Action里, 取出object类型的参数转换为Window对象就行了,然后就可以关闭这个窗体。

虽然这个方法可行,但这不符合mvvm的设计思想, ViewModel不应该依赖于View。  请问还有其他更好的解决办法吗?

------解决方案--------------------
呵呵,没啥符合不符合,写代码不是套框框。尤其在局部代码上面

首先为啥会有MVVM??MVVM出现旨在简化绑定和数据同步过程,这是MVVM最核心的思维,至于其他的那些个框框其实无所谓

所以就算我有方法可以搞,我也不会告诉你,因为我不想你去套框框,这些东西在局部上我愿意去尊重事实,而不是为了套框框把自己给埋坑里

ps:何谓ViewModel,场景数据视图模型,本身就和UI息息相关,很难用一堵墙就隔开了。如果你不想这边订阅那边,你就那边订阅这边好了
------解决方案--------------------
在你的场景中,XAML的作用就是直接匹配程序员的编程代码。如果你说“code-behind代码可以依赖于View”,那么你又怎么能说“ViewModel不应该依赖于View”呢?

你因为怀疑你自己的写法不符合这句话,于是做出了更加违背这句话的选择。两者相害,“取其轻”吧!还是在code-behind中尽量避免依赖于View,而仅仅在XAML的代码中依赖于View自己吧。
------解决方案--------------------
其实你完全可以封装一个较高层次的Behavior,在Blend上直接拖到控件上就行了,而根本不用给它设置什么Window参数。因为它(你写的代码)可以直接从宿主控件向上而找到Window类型的控件。

实际上我们写代码,是可以访问View的。但是我们应该仅仅在工具里边这样写,然后把工具发布出来的目的用来达到MVVM分离式开发方法的。而不是在我们最终的应用程序中这样写代码。
------解决方案--------------------
想想吧。任何一个好模式都不是给所有层次的人使用的,如果你能占到高处去创造,那么你就能让那些刚入门的人更好地复用你给他们铺下的道路。这就好像是工地上的建筑工人必须按照建筑师的图纸来工作,而甚至根本平常见不着建筑师。

如果你只是会给他们写个最简单的实例以此为指导,他们绝对不会理解分层次设计好处,他们会愤青地偷偷说“我真不想用他的代码,我打算下次装傻充愣故意听不懂他的设计”。

因此如果你不能为别人创造工具,如果你写的代码跟那些只能写最终应用代码的工人的一样,那么微软的什么MVVM自然也就不会被你所接受。