在 WPF Prism MVVM 的同一模块中切换视图

Switching views in the same module for WPF Prism MVVM

我试图了解如何在使用 prism 和 unity 的 wpf mvvm 应用程序中切换视图及其视图模型。我从教程中整理了一些内容,但还有其他问题,因为有些事情似乎不对。到目前为止,我拥有的是一个带有 shell.xaml window 的 WPF 应用程序,它具有使用棱镜区域的部分占位符。此外,我有一个引导程序 class 用于注册模块,这些模块将填充 shell.xaml window 中的不同区域。在 class 库的模块中,我具有设置视图和视图模型的初始化函数。我在这个应用程序中只有两个区域,导航和工作区。我在导航上有 2 个按钮,它们会更改工作区中的视图。工作区视图位于它们自己的模块中。所以此时每个工作区视图都有自己的 class 库模块。在大型应用程序中,让每个视图都有自己的 class 库似乎是不合理的。我想知道如何在一个 class 库中拥有多个视图和视图模型并将它们换入换出。如果你有一个很好的分步教程那就太好了。

您可以根据需要在模块中拥有任意数量的视图。您只需要浏览它们即可。为此,您需要注册它们,然后您可以请求从每个视图模型导航到区域管理器的另一个视图。看这里 prism navigation

我知道这已经晚了4年,但我还是会给出答案的。 您要做的第一件事是将您需要的视图添加到 Views 文件夹,并在 ViewModels 文件夹中添加它们相应的 ViewModel,这样您就拥有如下所述的结构:

视图模型

  • ViewModelA
  • ViewModelB

观看次数

  • 视图A
  • 视图B

ViewModel 及其相应的视图可能如下所示:

ViewModelA

using System;

namespace SomeApp.DemoModule.ViewModels
{
    public class ViewModelA : INavigationAware
    {
        public ViewModelA(IUnityContainer container, IRegionManager regionManager, IEventAggregator eventAggregator)
        {
            this.container = container;
            this.regionManager = regionManager;
            this.eventAggregator = eventAggregator;
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            //Do stuff here

            //For navigation back
            navigationService = navigationContext.NavigationService;
        }

        #region Executes
        /// <summary>
        /// Command when ViewB button clicked
        /// </summary>
        public void Execute_ViewBCommand()
        {
            regionManager.RequestNavigate("REGIONNAME_HERE", new Uri("ViewB", UriKind.Relative));
        }

视图A

<UserControl x:Class="DemoModule.Views.ViewA"
         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:ViewInjection.Views"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
  <Button Content="VIEWB" FontSize="38" Command="{Binding ViewBCommand}"></Button>
</Grid>

ViewA.Xaml.cs

   namespace SomeApp.DemoModule.Views
{
    /// <summary>
    /// Interaction logic for ViewA.xaml
    /// </summary>
    public partial class ViewA : UserControl
    {
        public ViewA(ViewModelA model)
        {
            InitializeComponent();
            this.DataContext = model;
        }
    }
}

ViewModelB

    using System;

namespace SomeApp.DemoModule.ViewModels
{
    public class ViewModelB : INavigationAware
    {
        public ViewModelB(IUnityContainer container, IRegionManager regionManager, IEventAggregator eventAggregator)
        {
            this.container = container;
            this.regionManager = regionManager;
            this.eventAggregator = eventAggregator;
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            //Do stuff here

            //For navigation back
            navigationService = navigationContext.NavigationService;
        }

        #region Executes
        /// <summary>
        /// Command when ViewA button clicked
        /// </summary>
        public void Execute_ViewACommand()
        {
            regionManager.RequestNavigate("REGIONNAME_HERE", new Uri("ViewA", UriKind.Relative));
        }

视图B

 <UserControl x:Class="DemoModule.Views.ViewB"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
  <Button Content="VIEWA" FontSize="38" Command="{Binding ViewACommand}"></Button>
</Grid>

ViewB.Xaml.cs

   namespace SomeApp.DemoModule.Views
{
    /// <summary>
    /// Interaction logic for ViewB.xaml
    /// </summary>
    public partial class ViewB : UserControl
    {
        public ViewB(ViewModelB model)
        {
            InitializeComponent();
            this.DataContext = model;
        }
    }
}

您可以通过多种方式注册您的视图,我们在注册视图的项目根目录中使用 DemoModuleInit class :

DemoModuleInit

public class DemoModuleInit : IModule
{
    private IRegionManager regionManager;

    /// <summary>
    /// Bind your interfaces, subscribe to events, do stuff that needs to be done on intialization of module
    /// </summary>
    public void OnInitialized(IContainerProvider containerProvider)
    {
        // Setup Event listeners etc...
        regionManager = containerProvider.Resolve<IRegionManager>();
    }

    /// <summary>
    /// Register your views for this Module
    /// </summary>
    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        containerRegistry.RegisterForNavigation<ViewA>();
        containerRegistry.RegisterForNavigation<ViewB>();
    }

如果实施正确,您应该能够在同一模块中从 ViewA 导航到 ViewB 并返回 有关 Prism 的更多信息,请查看: Prsim on GitHub