我正在尝试使用MVVM模式在视图之间设置导航。我的应用程序包含A mainWindow ,每个按钮都有两个视图。当我单击 view1 中的按钮时,我想在 mainwindow 中设置 view2 。。
我找到了几个教程女巫说明了如何从视图到另一个按钮在主窗口上的按钮(模拟TabControl(,但它不是我想要的。
我正在寻找:
view1_view.xaml.cs:
public partial class View1_View : UserControl
{
private View1_ViewModel _viewModel = new View1_ViewModel();
public View1_View()
{
InitializeComponent();
}
private void Btn_SwitchToView2_Click(object sender, RoutedEventArgs e)
{
MainWindow.SwitchToView2();
}
}
mainwindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new View1_View();
}
public void SwitchToView2()
{
this.DataContext = new View2_View();
}
}
我的问题是,如果我这样做,从类 view1_view 我无法访问方法 switchtoview2((如果不是 static ,如果是静态的话,我会失去MainWindow的上下文。
我应该如何进行?谢谢。
我建议使用ContentControl
切换主视图的一部分。
这看起来像这样(简短的形式只是为了给您一个想法;没有INotifyPropertyChanged
(。
创建一个类型ISwitchableViewModel
的空接口。
将属性添加到您的主ViewModel
public property ISwitchableViewModel MyViewModel {get; set;}
创建两个实现接口ISwitchableViewModel
的类。每个要显示的视图(示例中的View1
和View2
(,并称其为ViewModel1
和ViewModel2
。
按下XAML中的按钮时,将MyViewModel
设置为View1
或View2
;无论您的逻辑是什么。
在您的XAML中,在您要显示可切换内容的地方添加此内容。
<ContentControl Content="{Binding MyViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewModel:ViewModel1}">
<view:View1 />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:ViewModel2}">
<view:View2 />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
当您在MainViewModel
中设置MyViewModel
时,UI将自动显示该ViewModel的正确视图。
您可以通过创建视图并将其分配给内容控件来实现。
假设您在主视图中具有此内容控件。
<Window x:Class="MVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MVVM"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button x:Name="ChangeView" Click="SwitchToSecondView" Content="Set View"></Button>
<ContentControl x:Name="MainContent"></ContentControl>
</StackPanel>
</Window>
您可以在主视图的文件后面的代码中设置内容。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void SwitchToSecondView(object sender, outedEventArgs e)
{
var view = new SecondView();
var model = new SecondViewModel(this);
view.DataContext = model;
MainContent.Content = view;
}
public void SwitchToThirdView(object sender, outedEventArgs e)
{
var view = new ThirdView();
var model = new ThirdViewModel(this);
view.DataContext = model;
MainContent.Content = view;
}
}
另一个解决方案是使用MVVM Framework Light caliburn.micro,Prism等,这与上面的代码段相同,但请隐藏样板代码。
编辑:我意识到我没有明确地进入您问题的第二部分。
通常,一个可以控制导航的路由器。为了简单起见,我们将主视图用作路由器。要访问主视图,您需要将其注入每个组件。
这允许您的每个子模型访问主视图。
可以通过使用某种Di-container或通过调解员来改善这一点。调解员将允许每个组件发送请求,然后将其派发到主视图,消除直接依赖。