【发布时间】:2019-07-26 06:44:20
【问题描述】:
我正在尝试创建一个 WPF 应用程序,对于导航,我使用的是我在
找到的示例https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/
现在,我需要在单击按钮时从一个 UserControl 导航到另一个。
有人可以指导我如何使用 MVVM 实现这一目标吗?或者我是否应该考虑使用一些导航框架。
【问题讨论】:
我正在尝试创建一个 WPF 应用程序,对于导航,我使用的是我在
找到的示例https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/
现在,我需要在单击按钮时从一个 UserControl 导航到另一个。
有人可以指导我如何使用 MVVM 实现这一目标吗?或者我是否应该考虑使用一些导航框架。
【问题讨论】:
这在一定程度上取决于上下文,但很多时候我使用的技术是在某个 ViewModel 中有一个名称类似于“MainContent”的对象(或某种抽象类)。这负责保存要在ContentControl 中显示的内容。
我的 XAML 看起来像这样,其中 Type1View 和 Type2View 将是 UserControls(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的回复。)
【讨论】:
Type1ViewModel 如果您还没有实例化它,它将为空。因此,您可以实例化它并将其保存在内存中(可能在构造函数中),或者您可以尝试private void NavigateToType1() => MainContent = new Type1ViewModel();。