Prism进入视图时导航的三种方式

  • Prism进入视图时导航的三种方式已关闭评论
  • 273 次浏览
  • A+
所属分类:.NET技术
摘要

新建视图UserControl及其ViewModel,被跳转的视图的VM需要实现INavigationAware在App.xaml.cs中注册视图及其ViewModel


Prism导航

  1. 新建视图UserControl及其ViewModel,被跳转的视图的VM需要实现INavigationAware

  2. App.xaml.cs中注册视图及其ViewModel

// App.xaml.cs containerRegistry.RegisterForNavigation<IndexView, IndexViewModel>(); 
  1. 在需要放置导航内容处声明ContentControlregion占位:
    <DockPanel LastChildFill="True">         <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="5" >             <Button Command="{Binding NavigateCommand}" CommandParameter="ViewA" Margin="5">Navigate to View A</Button>             <Button Command="{Binding NavigateCommand}" CommandParameter="ViewB" Margin="5">Navigate to View B</Button>         </StackPanel>         <ContentControl prism:RegionManager.RegionName             ="{x:Static ext:PrismManager.MainViewRegionName}" />     </DockPanel> 
  • RegionPrism内部的一个数据结构,它的Name属性是此处在XAML中声明的RegionName(详见下节)。
  1. 在需要进行导航行为的ViewModel处注入并使用,如:
// ViewModel         public DelegateCommand<string> NavigateCommand { get; private set; }          public MainWindowViewModel(IRegionManager regionManager)         {             _regionManager = regionManager;              NavigateCommand = new DelegateCommand<string>(Navigate);         }          private void Navigate(string navigatePath)         {             if (navigatePath != null)                 _regionManager.RequestNavigate("ContentRegion", navigatePath);         } 

RegionManager

Prism进入视图时导航的三种方式

  • Region 对应的是在XAML中声明的 ContentControl 的附加属性 prism:RegionManager.RegionName

  • RegionManager 管理着所有 Region 对象,这些 Region 对象被装到 RegionCollection 中的列表属性

  • RegionManager中的3个方法

    • UpdateRegionsPrismApplicationBase#Initialize 中被调用,它会根据在XAML中声明的RegionName 创建 Region 对象
    • RequestNavigate 在需要导航时调用,调用它时会根据 regionName 去 regionCollection 中找到对应的 Region 对象,并通过集合 ActiveViews 找到满足条件的 View 实例从而进行 ContentControl内容的切换
    • 可以主动调用 RegisterViewWithRegion 进行 Region 和视图的注册

在进入视图时导航

由于 View 和 ViewModel 的初始化 MvvmHelpers.AutowireViewModel(shell); 先于 Region 的初始化RegionManager.UpdateRegions();,因此在View和ViewModel初始化时找不到相应的 Region 对象。

// PrismApplicationBase.cs protected virtual void Initialize() {     // ...     if (shell != null)     {         MvvmHelpers.AutowireViewModel(shell);         RegionManager.SetRegionManager(shell, _containerExtension.Resolve<IRegionManager>());         RegionManager.UpdateRegions();         InitializeShell(shell);     }     // ... 

在窗口初始化时,Initilized 事件发生时数据绑定未完成;Loaded 事件发生时数据绑定已经完成。

因此,可以手动注册 Region;也可以在数据绑定结束之后访问 Region

方法1 Loaded事件

private void Window_Loaded(object sender, RoutedEventArgs e) {     regionManager.RequestNavigate("ContentRegion", "ViewA"); } 

方法2 手动注册 Region

// App.xaml.cs protected override void Initialize() {     base.Initialize();      var regionManager = Container.Resolve<IRegionManager>();     regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA)); }  // ViewModel public MainWindowViewModel(IRegionManager regionManager) {     regionManager.RequestNavigate("ContentRegion", "ViewA"); } 

方法3 Dispatcher

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => {     regionManager.RequestNavigate("ContentRegion", "ViewA"); })); 

引用

  1. Prism - Region navigation
  2. learn.microsoft - Object lifetime events (WPF .NET)