在我的silverlight应用程序中,用户可以创建表单的多个模板。根据所选的模板,表单将按特定顺序显示一组视图。此外,如果模板上存在某些视图是“必需的”。客户希望这些视图以弹出形式显示,以便用户在转移到表单上的其他视图之前首先关注那些“必需”视图。
现在,我发现自己打破了这个要求的MVVM模式。这就是为什么...... 1. ViewModel可以从db读取模板,抓取视图(使用MEF)但是要将它们添加到表单中,它需要知道布局网格的名称并将视图作为子项添加到该网格。这就像告诉ViewModel关于针对MVVM设计模式的UI元素。
我确信我的方法存在缺陷,但我无法找到一种方法将UI逻辑与业务逻辑完全分开。有人可以提供更好的方法。
感谢。 甲
答案 0 :(得分:3)
恕我直言:这是另一种情况,只需将控制器添加到MVVM就可以彻底解决所有问题。我们称之为MVCVM(羞耻不等于有效的罗马数字):)
我们在所有最近项目中成功使用的模式是在模块中注册控制器仅,并在启动时初始化它们。控制器非常轻薄,是唯一需要在应用程序监听或发送消息的生命周期中闲逛的东西。在他们的初始化方法中,他们然后注册他们需要拥有的任何东西(视图和视图模型等)。这种轻量级逻辑内存模式也可以实现更轻薄的应用程序(例如WP7更好)。
正如您所发现的那样,使用虚拟机的问题是,最终您遇到了需要了解视图的情况(这是他们永远不知道的一件事)。
我们遵循的基本规则是:
最后两点是你永远不应该打破的点,或者关注点的分离会消失。
到目前为止,您需要您的VM直接访问数据库(糟糕),您的虚拟机获取视图(非常糟糕),并且要求您的虚拟机弹出另一个窗口(非常糟糕)。
考虑一下。您可能会(重新)将控制器引入MVVM应用程序。如果您想要更多信息,请询问。
答案 1 :(得分:0)
在我们的项目中,当需要在需要UI特定事物时在视图和视图模型之间进行通信时,我们一直在遵循事件订阅机制。解决问题的一种方法是在视图模型上发布一个事件,并将视图列表作为事件参数。或者可以有一个维护此列表的属性,在视图模型上设置,并在更新属性时触发事件。在视图中,您可以订阅事件并将控件添加到布局根目录。这是一个可测试的解决方案,并没有在视图模型中放置任何特定的视图。
如果您可以自由使用MVVM框架,那么您可以尝试使用PRISM或MVVMLight。 Prism提供事件同意者,而MVVMLight提供Messenger类,可以分离视图和视图模型之间的通信以及不同的视图模型。
答案 2 :(得分:0)
这是我想到的解决方案。
1.使用带有ViewModel关联的View名称的元标记来装饰ViewModel。
创建一个名为ViewViewModel的新类,它包含两个属性
在窗体ViewModel上,它负责将所有视图聚合在一起,并根据具体情况调出子窗口。添加三个属性
FormView模型将实例化所需的视图模型,从其MEF元标记中收集每个视图模型的视图名称,并填充FormView和ChildWindowView属性。完成Form ViewModel处理请求并填充了两个属性后,如果ChildWindow不为空,它将使用true参数触发ShowWindow委托。
表单视图将执行以下操作
布局根将具有绑定到FormView属性的堆栈面板。将有一个IValueConverter处理FormViews列表中的每个条目。对于每个ViewName,它查找并创建视图的intance。将DataContext设置为ViewModel。
当引发ShowChildWindow操作时,它创建的Form View中的代码隐藏最少,并显示绑定到ChildWindowViews属性的ChildWindow。 ChildWindow属性使用相同的IValueCOnverter来创建所请求视图的实例。
听起来怎么样?请评论
enter code here