我试图学习mvvm模式(c),它来自windows窗体背景。我正在使用mvvm light工具包,到目前为止我认为它非常出色。
我已经做了几个小的应用程序,但有一件事我正在努力介绍第二个视图。
例如,我想在mainviewmodel上有一个按钮,它通过relaycommand打开一个新窗口,比如说“about”窗口。为此,我在网上做了几个小时的研究,但似乎无法让aboutview模型与aboutview通信/显示aboutview。
我已经在aboutview.xaml的代码隐藏构造函数中放置了一个接收信使-但是我无法让它接收来自aboutview模型的任何消息,因此无法使其成为“show()”。
如果有人有一个使用多个视图的mvvm light wpf应用程序的示例,那就太好了:)
最佳答案
我想有两种方法可以轻易做到这一点
第一种方法是使用Popup
而不是新的Window
。例如,我经常为ViewModel
和PopupContent
将属性放入我的IsPopupVisible
中,并随时设置这些值以显示我的Popup
控件。例如,ShowAboutPopup
中继命令可能会运行如下:
void ShowAboutPopup()
{
PopupContent = new AboutViewModel();
IsPopupVisible = true;
}
您可以使用
Popup
对象或自定义UserControl
来显示它。我更喜欢使用自己的custom Popup UserControl,它通常看起来像这样:<Window>
<Canvas x:Name="RootPanel">
<SomePanel>
<!-- Regular content goes here -->
</SomePanel>
<local:PopupPanel Content="{Binding PopupContent}"
local:PopupPanel.IsPopupVisible="{Binding IsPopupVisible}"
local:PopupPanel.PopupParent="{Binding ElementName=RootPanel}" />
</Canvas>
</Window>
PopupContent
属性是一个ViewModel
(例如AboutViewModel
),并且DataTemplates
用于告诉wpf用特定的ViewModels
绘制特定的Views
。<Window.Resources>
<DataTemplate DataType="{x:Type local:AboutViewModel}">
<local:AboutView />
</DataTemplate>
</Window.Resources>
另一种方法是让某种
ApplicationViewModel
在启动时运行,并负责整个应用程序状态,包括哪些窗口处于打开状态。通常,我更喜欢使用包含
ApplicationView
的单个ContentControl
来显示当前页<Window>
<ContentControl Content="{Binding CurrentViewModel}" />
</Window>
但是,它也可以用于管理多个窗口。如果您确实使用它来管理多个
Window
对象,请注意这将不是一个纯ViewModel
对象,因为它需要访问某些视图特定的对象,并且引用ui对象,这不是ViewModel
应该做的事情。例如,它可以订阅receiveShowWindow
消息,在收到这些消息时,它将创建指定的视图并显示它,还可能隐藏当前窗口。就我个人而言,我尽量避免使用多个窗口。我通常的方法是有一个单独的视图,其中包含任何页面的一致应用程序对象,还有一个
ContentControl
包含更改的动态内容。如果你感兴趣的话我有一个