在 MVVM wpf 中切换视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42229838/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 14:00:32  来源:igfitidea点击:

switching views in MVVM wpf

c#wpfmvvmuser-controls

提问by Json

I Know that my problem is a common one but every solution I found is not the one I really need. Here is my problem : I want to be able to switch between different usercontrol in the mainWindow. All the solution I found consist of having a menu in the main window and every button brings the corresponding userControl, like this exemple : https://rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/

我知道我的问题很常见,但我找到的每一个解决方案都不是我真正需要的。这是我的问题:我希望能够在主窗口中的不同用户控件之间切换。我找到的所有解决方案都包括在主窗口中有一个菜单,每个按钮都带有相应的 userControl,例如:https: //rachel53461.wordpress.com/2011/12/18/navigation-with-mvvm-2/

But what i want is more like : at the begining, the mainwindows has the UserControl1 into it. In the userControl1 there would be 1 buttons who change the content of the mainWindow with a new userControl (userControl2 for instance)

但我想要的更像是:在开始时,主窗口将 UserControl1 放入其中。在 userControl1 中,将有 1 个按钮使用新的 userControl(例如 userControl2)更改 mainWindow 的内容

enter image description here

在此处输入图片说明

the xaml of mainWindow

mainWindow的xaml

<Window x:Class="DataTemplateSO_Learning.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataTemplateSO_Learning"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>       
        <DataTemplate DataType="{x:Type local:EmployeeViewModel}">
            <local:EmployeeView/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:DepartmentViewModel}">
            <local:DepartmentView/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:MenuViewModel}">
            <local:MenuView/>
        </DataTemplate>
    </Window.Resources>
    <DockPanel LastChildFill="True">
        <ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}"/>
    </DockPanel>
</Window>

the cs of my mainWindow :

我的 mainWindow 的 cs :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Pages.Content = new MenuView();
        this.DataContext = new NavigationViewModel();
    }
}

the xaml of my first page :

我的第一页的 xaml :

<UserControl x:Class="DataTemplateSO_Learning.MenuView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:DataTemplateSO_Learning"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <DockPanel LastChildFill="True">
        <StackPanel x:Name="navigation" DockPanel.Dock="Left" VerticalAlignment="Center">
            <Button Content="Employee" Command="{Binding EmpCommand}"></Button>
            <Button Content="Department" Command="{Binding DeptCommand}"></Button>
        </StackPanel>
    </DockPanel>
</UserControl>

my first page View :

我的第一页视图:

public partial class MenuView : UserControl
{
    public MenuView()
    {
        InitializeComponent();
        this.DataContext = new MenuViewModel();
    }
}

the viewModel of my first page :

我的第一页的 viewModel :

class MenuViewModel 
{
    public ICommand EmpCommand { get; set; }
    public ICommand DeptCommand { get; set; }

    public MenuViewModel()
    {
        EmpCommand = new BaseCommand(OpenEmp);
        DeptCommand = new BaseCommand(OpenDept);
    }

    private void OpenEmp(object obj)
    {
        SelectedViewModel = new EmployeeViewModel();
    }
    private void OpenDept(object obj)
    {
        SelectedViewModel = new DepartmentViewModel();
    }
}

of course he doesn't know "SelectedViewModel" because it's bind to the control of mainWindow

当然他不知道“SelectedViewModel”,因为它绑定到mainWindow的控件

my navigationViewModel :

我的导航视图模型:

class NavigationViewModel : INotifyPropertyChanged
{
    private object selectedViewModel;

    public object SelectedViewModel
    {
        get
        {
            return selectedViewModel;
        }
        set
        {
            selectedViewModel = value;
            OnPropertyChanged("SelectedViewModel");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

}

Thank you very much for your help !

非常感谢您的帮助 !

回答by mm8

You could for example inject the MenuViewor MenuViewModelwith a reference to the MainViewModel:

例如,您可以注入MenuViewMenuViewModel引用MainViewModel

MainWindow.xaml.cs:

主窗口.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        var viewModel = new NavigationViewModel();
        viewModel.SelectedViewModel = new MenuViewModel(viewModel);
        this.DataContext = viewModel;
    }
}

MenuViewModel.cs:

MenuViewModel.cs:

class MenuViewModel
{
    public ICommand EmpCommand { get; set; }
    public ICommand DeptCommand { get; set; }

    private readonly NavigationViewModel _navigationViewModel;

    public MenuViewModel(NavigationViewModel navigationViewModel)
    {
        _navigationViewModel = navigationViewModel;
        EmpCommand = new BaseCommand(OpenEmp);
        DeptCommand = new BaseCommand(OpenDept);
    }

    private void OpenEmp(object obj)
    {
        _navigationViewModel.SelectedViewModel = new EmployeeViewModel();
    }
    private void OpenDept(object obj)
    {
        _navigationViewModel.SelectedViewModel = new DepartmentViewModel();
    }
}

MenuView.xaml.cs:

MenuView.xaml.cs:

public partial class MenuView : UserControl
{
    public MenuView()
    {
        InitializeComponent();
    }
}