WPF Window 使用 MVVM 而不是框架(甚至不是 MSFT)的导航

WPF Window Navigation using MVVM but not frameworks(not even MSFT)

只是为了不将其标记为重复项。我发现了很多类似的问题,但它们依赖于框架的使用(第 3 部分或基于 MSFT)。还有一些建议内置的页面导航功能,这不是我想要的。

现在回到最初的问题。

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

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

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


首先,重要的是要注意没有代码隐藏不是 MVVM 中的要点。它是关于将代码放在它所属的地方。因此,从 Button 的点击事件中打开 Window 是完全有效的,因为它是 查看相关代码 .

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

尽量不要陷入代码隐藏是错误代码的想法中,因为事实并非如此。


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

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 将服务注入视图模型,请参阅 here。这里需要注意的是,我使用的是 interface,这使我能够抽象出 window 服务的实现,这当然是一件好事。

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

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

差不多就这些了。