WPF窗口导航使用MVVM,但不是框架(甚至不是MSFT)

本文关键字:框架 MSFT 导航 窗口 MVVM WPF | 更新日期: 2023-09-27 18:19:16

这样它就不会被标记为重复。我发现了很多类似的问题,但它们依赖于框架的使用(要么是第三方的,要么是基于MSFT的)。也有人建议内置的页面导航功能,这不是我所寻找的。

现在回到最初的问题。

我正在开发一个MVVM模式的WPF应用程序,没有Prism或任何框架,只是基本的MVVM概念。我希望从窗口1 (Login)导航到窗口2 (MainWindow),然后回到窗口1 (Logout)。我正在努力了解实现这一目标的最佳方式。我不是在寻找一个变通方法,而是概念方法来处理这种情况,以更好地理解MVVM。

WPF窗口导航使用MVVM,但不是框架(甚至不是MSFT)

Window导航在MVVM模式下有点棘手。该模式最适合Page导航,或SPA(单页应用程序)用户界面。

但是,这并不意味着没有框架就不能完成。


首先,重要的是要注意,在MVVM中,没有不是的代码隐藏点。它是关于把代码放在它属于的地方。因此,从Button的单击事件打开Window是完全有效的,因为它是视图相关代码的一部分。

private void Button_Clicked(object sender, RoutedEventArgs e)
{
   MyView view = new MyView();
   view.Show();
}

尽量不要陷入代码隐藏是坏代码的想法,因为它不是。


为了使视图模型与窗口打开逻辑分离,将其封装在服务中是个好主意。让我们看一个非常简单的例子:

public interface IWindowService
{
    void OpenView(object viewModel);
}
public class WindowService
{
    public void OpenView(object viewModel)
    {
        //Use reflection to get the view based on the view model name.
        //Open the view
        //Set the DataContext to be the view model.
    }
}

注意:我不打算用太多的代码,这纯粹是从概念的角度来看。

这个服务很简单,有一个方法需要一个视图模型,在此基础上,它会找到关联的视图,打开它,设置DataContext。简单的很。

这个服务可以扩展到处理对话框和诸如此类的

为了使用这个服务,我们需要注入到视图模型中,应该是这样做的:
public class MyViewModel
{
    private IWindowService _WindowService;
    public MyViewModel(IWindowService windowService)
    {
        _WindowService = windowService;
    }
    ...
}

你可以使用Dependency Injection将服务注入到视图模型中,见这里。这里需要注意的是,我使用的是interface,这允许我抽象出窗口服务的实现,这当然是一件好事。

剩下的就是打开一个视图,这可以通过调用OpenView方法来完成:

SomeOtherViewModel myOtherViewModel = new SomeOtherViewModel();
_WindowService.OpenView(myOtherViewModel);