我认为有两种方法可以轻松做到这一点
第一种是使用 aPopup
而不是 new Window
。例如,我经常将属性放在我ViewModel
的 forPopupContent
和IsPopupVisible
中,并在我想显示我的Popup
控件的任何时候设置这些值。例如,一个ShowAboutPopup
中继命令可能会像这样运行:
void ShowAboutPopup()
{
PopupContent = new AboutViewModel();
IsPopupVisible = true;
}
您可以使用Popup
对象或自定义来显示它UserControl
。我更喜欢使用我自己的自定义 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
属性是 a ViewModel
(如 a )AboutViewModel
,DataTemplates
用于告诉 WPF 以特定的方式绘制特定ViewModels
的Views
<Window.Resources>
<DataTemplate DataType="{x:Type local:AboutViewModel}">
<local:AboutView />
</DataTemplate>
</Window.Resources>
另一种方法是让某种ApplicationViewModel
在启动时运行,并负责整个应用程序状态,包括打开哪些窗口。
通常我更喜欢有一个ApplicationView
包含 aContentControl
来显示当前页面
<Window>
<ContentControl Content="{Binding CurrentViewModel}" />
</Window>
但是它也可以用来管理多个窗口。如果您确实使用它来管理多个Window
对象,请注意这将不是纯粹的ViewModel
,因为它需要访问一些特定于视图的对象,并且引用 UI 对象不是ViewModel
应该做的事情。例如,它可能订阅接收ShowWindow
消息,并且在接收到这些消息后,它会创建指定的视图并显示它,并可能隐藏当前窗口。
就个人而言,我尽量避免使用多个窗口。我常用的方法是拥有一个包含任何页面的一致应用程序对象的单个视图,以及一个ContentControl
包含变化的动态内容。如果您有兴趣,我在我的博客上有一个使用这种导航样式的示例