简体   繁体   English

WPF查看谁使用MVVM导致另一个人

[英]WPF view who leads to another using MVVM

I am trying to set up a navigation between views using a MVVM pattern. 我试图使用MVVM模式在视图之间建立导航。 My application contains a MainWindow and two views with a button each. 我的应用程序包含一个MainWindow和两个视图,每个视图都有一个按钮。 When I click on the button in the View1 I want to set up the View2 on the MainWindow . 当我单击View1中的按钮时,我想在MainWindow上设置View2

I have found several tutorials witch explain how to navigate from a view to another with a button on the main window (simulate a tabControl), it works but it is not what I want. 我找到了几个教程,解释了如何通过主窗口上的按钮(模拟tabControl)从一个视图导航到另一个视图,它可以工作,但它不是我想要的。

I'm looking for something like : 我正在寻找类似的东西:

View1_View.xaml.cs : 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 : MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new View1_View();
    }

    public void SwitchToView2()
    {
        this.DataContext = new View2_View();
    }
}

My problem is if I do so, from the class View1_View I cannot access to the method SwitchToView2() if it is not static , and if it is static I lose the context of the MainWindow. 我的问题是如果我这样做,从类View1_View我不能访问方法SwitchToView2()如果它不是静态的 ,如果它是静态的我丢失了MainWindow的上下文。

How should I proceed ? 我该怎么办? Thanks. 谢谢。

I would recommend using a ContentControl to switch the part of your main view. 我建议使用ContentControl切换主视图的一部分。

This could look like this (short form just to give you an idea; without INotifyPropertyChanged ). 这可能看起来像这样(简短形式只是为了给你一个想法;没有INotifyPropertyChanged )。

Create an empty interface of type ISwitchableViewModel . 创建ISwitchableViewModel类型的空接口。

Add a property to your main ViewModel 将属性添加到主ViewModel

public property ISwitchableViewModel MyViewModel {get; set;}

Create two classes that implements the interface ISwitchableViewModel . 创建两个实现ISwitchableViewModel接口的ISwitchableViewModel Each for each view you want to show ( View1 and View2 in your example) and call them ViewModel1 and ViewModel2 . 每个视图都要显示(在您的示例中为View1View2 ),并将它们称为ViewModel1ViewModel2

When you press the button in your xaml set the MyViewModel to View1 or View2 ; 当您按下xaml中的按钮时,将MyViewModel设置为View1View2 ; whatever your logic is. 无论你的逻辑是什么。

In your xaml add this at the place where you want to show the switchable content. 在您的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>

When you set the MyViewModel in your MainViewModel the UI will show automatically the correct view for that viewmodel. 当您在MainViewModel设置MyViewModel ,UI将自动显示该视图模型的正确视图。

You can achieve this by creating the views and assigning them to a content control. 您可以通过创建视图并将其分配给内容控件来实现此目的。

Lets assume you have this content control in your main view. 让我们假设您在主视图中有此内容控件。

<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>

You can then set the content in the code behind file of your main view. 然后,您可以在主视图的代码隐藏文件中设置内容。

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;
   }
}

Another solution would be to use an MVVM Framework light Caliburn.Micro, Prism etc, which essential do the same thing as the code snippet above, but hide the boilerplate code. 另一种解决方案是使用MVVM Framework轻型Caliburn.Micro,Prism等,它与上面的代码片段完全相同,但隐藏样板代码。

EDIT: I realized i didn't explicitly get to the second part of your question. 编辑:我意识到我没有明确地谈到你问题的第二部分。

Usally one would need some kind of router which is able to control the navigation. 通常需要某种能够控制导航的路由器。 For the sake of simplicity we use the main view as router. 为简单起见,我们使用主视图作为路由器。 To access the main view, you need to inject it in each component. 要访问主视图,您需要将其注入每个组件中。

This allows each of your submodels to access the main view. 这允许您的每个子模型访问主视图。

This could be improved by using some kind of DI-Container or by a Mediator. 这可以通过使用某种DI-Container或Mediator来改进。 A mediator would allow each component to send requests, which then are dispatched to the MainView, eliminating the direct dependency. 中介将允许每个组件发送请求,然后将其分派到MainView,从而消除直接依赖性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM