WPF MVVM 在按钮单击时在视图之间导航
Posted
技术标签:
【中文标题】WPF MVVM 在按钮单击时在视图之间导航【英文标题】:WPF MVVM Navigate between Views on button click 【发布时间】:2019-07-26 06:44:20 【问题描述】:我正在尝试创建一个 WPF 应用程序,对于导航,我使用的是我在
找到的示例https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/
现在,我需要在单击按钮时从一个 UserControl 导航到另一个。
有人可以指导我如何使用 MVVM 实现这一目标吗?或者我是否应该考虑使用一些导航框架。
【问题讨论】:
【参考方案1】:这在一定程度上取决于上下文,但很多时候我使用的技术是在某个 ViewModel 中有一个名称类似于“MainContent”的对象(或某种抽象类)。这负责保存要在ContentControl
中显示的内容。
我的 XAML 看起来像这样,其中 Type1View
和 Type2View
将是 UserControl
s(vw_Type1
和 vw_Type2
是对其命名空间的引用),然后我将通过设置 @ 在它们之间导航987654328@ 到 Type1ViewModel
或 Type2ViewModel
的实例。
<ContentControl Content="Binding MainContent">
<ContentControl.Resources>
<DataTemplate DataType="x:Type vm_Type1:Type1ViewModel">
<vw_Type1:Type1View />
</DataTemplate>
<DataTemplate DataType="x:Type vm_Type2:Type2ViewModel">
<vw_Type2:Type2View />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
这可能会通过ContentControl
之外的一个按钮(或以下示例中的两个按钮)来处理,该按钮向包含MainContent
的 ViewModel 发送一个命令,这只是更改了MainContent
属性,到Type1ViewModel
或Type2ViewModel
的现有或新实例。例如:
private Type1ViewModel _type1ViewModel;
public Type1ViewModel Type1ViewModel
get return _type1ViewModel;
set
if (_type1ViewModel != value)
_type1ViewModel = value;
NotifyPropertyChanged();
private Type2ViewModel _type2ViewModel;
public Type2ViewModel Type2ViewModel
get return _type2ViewModel;
set
if (_type2ViewModel != value)
_type2ViewModel = value;
NotifyPropertyChanged();
...
private ObservableObject _mainContent;
public ObservableObject MainContent
get return _mainContent;
set
if (_mainContent != value)
_mainContent = value;
NotifyPropertyChanged();
...
public InternalDelegateCommand NavigateToType1Command => new InternalDelegateCommand(NavigateToType1);
public InternalDelegateCommand NavigateToType2Command => new InternalDelegateCommand(NavigateToType2);
...
private void NavigateToType1() => MainContent = Type1ViewModel;
private void NavigateToType2() => MainContent = Type2ViewModel;
所以要完成此示例的 XAML:
<Button Content="Type 1" Command="Binding NavigateToType1Command" />
<Button Content="Type 2" Command="Binding NavigateToType2Command" />
<ContentControl Content="Binding MainContent">
<ContentControl.Resources>
<DataTemplate DataType="x:Type vm_Type1:Type1ViewModel">
<vw_Type1:Type1View />
</DataTemplate>
<DataTemplate DataType="x:Type vm_Type2:Type2ViewModel">
<vw_Type2:Type2View />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
(有关InternalDelegateCommand
的信息,请参阅我对this question的回复。)
【讨论】:
感谢您的帮助。但我有点困惑 MainContent 需要驻留在哪里。现在,当我按照您的示例并单击按钮时,MainContent 为空且私有 void NavigateToType1() => MainContent = Type1ViewModel,此处 Type1ViewModel 为空。 我发布的一段 C# 代码是 ViewModel 的部分视图,它是主视图的数据上下文(我发布的最后一段 XAML)。Type1ViewModel
如果您还没有实例化它,它将为空。因此,您可以实例化它并将其保存在内存中(可能在构造函数中),或者您可以尝试private void NavigateToType1() => MainContent = new Type1ViewModel();
。以上是关于WPF MVVM 在按钮单击时在视图之间导航的主要内容,如果未能解决你的问题,请参考以下文章
在 UserControl WPF MVVM caliburn 内的 UserControl 之间切换
关于使用 Caliburn.Micro MVVM WPF 进行视图导航的建议