我是WPF / MVVM的新手。我们当前的WPF项目仍然是原型应用程序,这意味着我们还没有设计主要布局。但我们确实设计了一些报告(通过报告,我的意思是一些相当复杂的UserControl
,其中每个都有一些配置控件,例如ComobBox
或TextBox
,以及一些DataGrid
,我们想要呈现的数据的Graph
控件为View
及其ViewModel
。它仍然是原型,所以我们只需要打开一个新的Window
,它会显示这些UserControl
中的任何一个。将来,我们可能会更改它以在主窗口内的不同区域中找到不同的UserControl
,就像Visual Studio的布局一样。主要观点是,我们的申请将包括近百个此类UserControl
或我们称之为报告的内容。所以它与我之前的具有静态布局/ MainView的工作项目不同。
我还没有想出一个好的架构。我们的经典使用场景是让用户在菜单报告中选择打开,因此我们有Command
(在MainViewModel或任何ViewModel报告中)对象来打开一个新报告。所以基本上Command
正在生成一个新的ViewModel
(ViewModel
第一个案例),然后应该生成相应的View
(由谁?),最后生成一个新的Window
应该打开1}},包括新生成的UserControl
。
我想我需要两项服务:
订阅新ViewModel生成的事件的服务,并在发生此类事件时解析UserControl
。
(对于我们当前的原型应用程序)一个窗口管理器,它订阅由1)服务发布的new-UserControl生成的事件,然后打开一个新窗口来显示它。
在未来的实际应用中,我们可以更改服务并将它们放入不同的区域。对于第二个,它很简单而且只是临时的,我可以在MainView的代码隐藏中有一个对象,它使用EventAggregator
订阅事件,并生成一个新的Window
。这是对的吗?
有人可以告诉我应该如何实现这个目标吗?
答案 0 :(得分:2)
数据绑定已经可以为您处理。在要显示报告的容器中,添加ContentControl
并将其绑定到包含当前要显示的报告的VM的属性。
<Window>
<ContentControl Content="{Binding Path=CurrentReport}" />
</Window>
要显示不同的报告,请将UserControls
中的每个DataTemplate
打包到可以注入ContentControl
的{{1}}中。要实际解析视图,您有几个选择。您可以创建DataTemplateSelector
来映射它们,或者只在模板上指定VM类型。在任何一种情况下,请确保模板位于ContentControl
的范围内(在同一文件中的Resources
或父级,或者从独立的ResourceDictionary
合并)。
<DataTemplate DataType="{x:Type viewModels:FirstReportViewModel}">
<views:FirstReportViewControl/>
</DataTemplate>
答案 1 :(得分:0)
要将视图与视图模型相关联,您可以在资源字典中使用数据模板。
<DataTemplate DataType="{x:Type vm:AllCustomersViewModel}">
<vw:AllCustomersView />
</DataTemplate>
您可能已经知道,可以在资源字典中设置名称空间。在此示例中,vw和vm分别引用包含视图模型和视图的文件夹。 现在,您可以使用内容控件通过绑定到视图模型来生成视图。
<ContentControl Content="{Binding SomeViewModel}" />
上面的代码已被Josh Smith btw无耻地窃取。
因此,您不需要服务来解析视图与viewmodel的关联。让框架为您完成工作。 我实际上不建议打开新窗口。如果必须,使用“窗口控制器” - 某种服务将是不可避免的。但是,我建议您坚持使用包含多个视图模型的单个窗口,并在接收到某些事件时进行交换。