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

问题描述 投票:0回答:2

我试图了解如何在使用棱镜和统一的wpf mvvm应用程序中切换视图及其视图模型。我从一个教程中把一些东西放在一起,但是有一些额外的问题,因为有些事情似乎不对。到目前为止,我所拥有的是一个带有shell.xaml窗口的WPF应用程序,该窗口具有使用棱镜区域的截面占位符。另外,我有一个bootstrapper类来注册模块,这些模块将填充shell.xaml窗口中的不同区域。在作为类库的模块中,我有初始化函数来设置视图和视图模型。我在这个应用程序中只有两个区域导航和工作区。我在导航上有2个按钮,它们会更改工作区中的视图。工作区视图位于各自的模块中。因此,此时每个工作空间视图都有自己的类库模块。在一个大型应用程序中,让每个视图都有自己的类库似乎是不合理的。我想知道如何在一个类库中拥有多个视图和视图模型,并将它们交换进去。如果你有一个很好的一步一步教程。

wpf mvvm unity-container prism
2个回答
0
投票

您可以根据需要在模块中拥有尽可能多的视图。你只需要浏览它们。为此,您需要注册它们,然后从每个视图模型中,您可以请求从您的regionmanager导航到另一个视图。看看这里prism navigation


0
投票

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

的ViewModels

  • ViewModelA
  • ViewModelB

查看

  • 埃瓦
  • ViewB

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

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

埃瓦

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

ViewB

 <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类来注册视图:

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

如果正确实施,您应该能够从View导航到View并返回到同一模块中。有关Prism的更多信息,请查看:qazxsw poi

© www.soinside.com 2019 - 2024. All rights reserved.