在 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
我试图了解如何在使用 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