Prism导航

news/2024/9/29 14:32:15

注册导航页面

注册区域

使用p:RegionManager.RegionName注册页面区域

<Window x:Class="WpfApp1.NavigationWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="clr-namespace:WpfApp1"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:p="http://prismlibrary.com/"Title="NavigationWindow"Width="800"Height="450"mc:Ignorable="d"><DockPanel><Grid Width="220" DockPanel.Dock="Left"><StackPanel><Button Margin="0,3"Command="{Binding OpenViewCommand}"CommandParameter="ViewA"Content="View A" /><Button Margin="0,3"Command="{Binding OpenViewCommand}"CommandParameter="ViewB"Content="View B" /><Button Margin="0,3" Content="View C" /></StackPanel></Grid><Grid><!--<ContentControl p:RegionManager.RegionName="ViewRegion"/>--><TabControl p:RegionManager.RegionName="ViewRegion"><TabControl.ItemContainerStyle><Style TargetType="TabItem"><!--  TabItem的绑定数据源是页面对象  --><!--  TabItem的DataContext=View对象  --><!--  View对象的DataContext=对应的ViewModel  --><Setter Property="Header" Value="{Binding DataContext.Title}" /></Style></TabControl.ItemContainerStyle></TabControl></Grid></DockPanel>
</Window>
public class NavigationWindowVewModel{public ICommand OpenViewCommand { get; set; }// 区域管理,需要拿到RegionManager
        IRegionManager _regionManager;public NavigationWindowVewModel(IRegionManager regionManager){_regionManager = regionManager;OpenViewCommand = new DelegateCommand<string>(DoOpenView);}private void DoOpenView(string viewName){_regionManager.RegisterViewWithRegion("ViewRegion", viewName);}}
 public class Startup : PrismBootstrapper{protected override DependencyObject CreateShell(){return Container.Resolve<NavigationWindow>();//return Container.Resolve<MainWindow>();
        }protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterForNavigation<ViewA>();containerRegistry.RegisterForNavigation<ViewB>();}protected override void ConfigureViewModelLocator(){base.ConfigureViewModelLocator();ViewModelLocationProvider.Register(typeof(NavigationWindow).ToString(), typeof(NavigationWindowVewModel));}}
<UserControl x:Class="WpfApp1.Views.ViewA"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="clr-namespace:WpfApp1.Views"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"d:DesignHeight="450"d:DesignWidth="800"mc:Ignorable="d"><StackPanel><TextBox FontSize="20" Foreground="Orange" Text="View A" /><TextBlock FontSize="20" Foreground="Red" Text="{Binding Title}" /><Button Command="{Binding CloseTabCommand}" Content="Close" /></StackPanel>
</UserControl>
<UserControl x:Class="WpfApp1.Views.ViewB"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="clr-namespace:WpfApp1.Views"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"d:DesignHeight="450"d:DesignWidth="800"mc:Ignorable="d"><Grid><TextBlock FontSize="20" Foreground="Green" Text="View B" /></Grid>
</UserControl>
 public class ViewAViewModel {public string Title { get; set; } = "View A";public ICommand CloseTabCommand { get; set; }IRegionManager _regionManager;public ViewAViewModel(IRegionManager regionManager){_regionManager = regionManager;CloseTabCommand = new DelegateCommand(DoCloseTab);}private void DoCloseTab(){}}
 public class ViewBViewModel 
    {public string Title { get; set; } = "View B";public ICommand CloseTabCommand { get; set; }IRegionManager _regionManager;public ViewBViewModel(IRegionManager regionManager){_regionManager = regionManager;CloseTabCommand = new DelegateCommand(DoCloseTab);}private void DoCloseTab(){}
}

导航页面传参——INavigationAware接口

 public class ViewAViewModel : INavigationAware{public string Title { get; set; } = "View A";public ICommand CloseTabCommand { get; set; }IRegionManager _regionManager;public ViewAViewModel(IRegionManager regionManager){_regionManager = regionManager;CloseTabCommand = new DelegateCommand(DoCloseTab);}private void DoCloseTab(){}#region INavigationAware接口方法public bool IsNavigationTarget(NavigationContext navigationContext){// 是否允许重复导航进来// 主-》A-》B-》A (显示前对象)  返回True// 主-》A-》B-》A(新对象)     返回falsereturn true;// 编辑页面,通过主页的子项点击,打开这个页面,// 子项有很多,可能同时打开多个子项进行编辑
        }public void OnNavigatedFrom(NavigationContext navigationContext){// 从当前View导航出去的时候触发// 从某个页面跳转到另一个页面的时候,可以把这个信息带过去navigationContext.Parameters.Add("abcd", "Hello ViewA");}public void OnNavigatedTo(NavigationContext navigationContext){// 打开当前View的时候触发string arg = navigationContext.Parameters.GetValue<string>("abcd");}#endregion}
 public class NavigationWindowVewModel{public ICommand OpenViewCommand { get; set; }// 区域管理,需要拿到RegionManager
        IRegionManager _regionManager;public NavigationWindowVewModel(IRegionManager regionManager){_regionManager = regionManager;OpenViewCommand = new DelegateCommand<string>(DoOpenView);}private void DoOpenView(string viewName){//_regionManager.RegisterViewWithRegion("ViewRegion", viewName);// 向某个View中传递特定参数,参数对接到View的ViewModel里if (viewName == "ViewA"){NavigationParameters parameters = new NavigationParameters();parameters.Add("abcd", "Hello");_regionManager.RequestNavigate("ViewRegion", viewName, parameters);}else if (viewName == "ViewB")_regionManager.RequestNavigate("ViewRegion", viewName);}}

自动销毁——IRegionMemberLifetime接口

页面的ViewModel继承IRegionMemberLifetime接口

接口中的KeepAlive参数默认为true:非激活状态,在Region中保留

public class ViewAViewModel : INavigationAware , IRegionMemberLifetime{public string Title { get; set; } = "View A";public ICommand CloseTabCommand { get; set; }IRegionManager _regionManager;public ViewAViewModel(IRegionManager regionManager){_regionManager = regionManager;CloseTabCommand = new DelegateCommand(DoCloseTab);}public bool KeepAlive => false;private void DoCloseTab(){}#region INavigationAware接口方法public bool IsNavigationTarget(NavigationContext navigationContext){// 是否允许重复导航进来// 主-》A-》B-》A (显示前对象)  返回True// 主-》A-》B-》A(新对象)     返回falsereturn true;// 编辑页面,通过主页的子项点击,打开这个页面,// 子项有很多,可能同时打开多个子项进行编辑
        }public void OnNavigatedFrom(NavigationContext navigationContext){// 从当前View导航出去的时候触发// 从某个页面跳转到另一个页面的时候,可以把这个信息带过去navigationContext.Parameters.Add("abcd", "Hello ViewA");}public void OnNavigatedTo(NavigationContext navigationContext){// 打开当前View的时候触发string arg = navigationContext.Parameters.GetValue<string>("abcd");}#endregion}

 

页面离开前的事件——IConfirmNavigationRequest接口

页面ViewModel实现IConfirmNavigationRequest接口

public class ViewAViewModel : INavigationAware,IRegionMemberLifetime,IConfirmNavigationRequest{public string Title { get; set; } = "View A";public ICommand CloseTabCommand { get; set; }IRegionManager _regionManager;public ViewAViewModel(IRegionManager regionManager){_regionManager = regionManager;CloseTabCommand = new DelegateCommand(DoCloseTab);}private void DoCloseTab(){}#region IRegionMemberLifetime接口方法// 用来控制当前页面非激活状态,是否在Region中保留public bool KeepAlive => true;#endregion#region INavigationAware接口方法#region INavigationAware接口方法public bool IsNavigationTarget(NavigationContext navigationContext){// 是否允许重复导航进来// 主-》A-》B-》A (显示前对象)  返回True// 主-》A-》B-》A(新对象)     返回falsereturn true;// 编辑页面,通过主页的子项点击,打开这个页面,// 子项有很多,可能同时打开多个子项进行编辑
        }public void OnNavigatedFrom(NavigationContext navigationContext){// 从当前View导航出去的时候触发// 从某个页面跳转到另一个页面的时候,可以把这个信息带过去navigationContext.Parameters.Add("abcd", "Hello ViewA");}public void OnNavigatedTo(NavigationContext navigationContext){// 打开当前View的时候触发string arg = navigationContext.Parameters.GetValue<string>("abcd");}#endregion#region IConfirmNavigationRequest接口方法// 当从当前页面跳转到另一个页面时触发// OnNavigatedFrom调用前执行public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback){// 打开某个页面,if (MessageBox.Show("是否离开当前页面?", "导航提示", MessageBoxButton.YesNo) ==MessageBoxResult.Yes){/// 继续打开/// continuationCallback?.Invoke(true);}else// 不被导航continuationCallback?.Invoke(false);}#endregion}

导航日志

编写测试程序

public class Startup : PrismBootstrapper
{protected override DependencyObject CreateShell(){return Container.Resolve<PrismRegion.Journal.Views.MainView>();}protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewA>();containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewB>();containerRegistry.RegisterForNavigation<PrismRegion.Journal.Views.ViewC>();}
}
public partial class App : Application
{public App(){new Startup().Run();}
}
<Window x:Class="Zhaoxi.PrismRegion.Journal.Views.MainView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:Zhaoxi.PrismRegion.Journal.Views"xmlns:p="http://prismlibrary.com/"mc:Ignorable="d"Title="MainView" Height="450" Width="800"><Grid><Button Content="Load Views" Command="{Binding BtnLoadCommand}" VerticalAlignment="Top"/><ContentControl p:RegionManager.RegionName="MainRegion" Margin="0,30,0,0"/></Grid>
</Window>
public class MainViewModel
{public DelegateCommand BtnLoadCommand { get; set; }public MainViewModel(IRegionManager regionManager){BtnLoadCommand = new DelegateCommand(() =>{regionManager.RequestNavigate("MainRegion", "ViewA");});}
}
<UserControl x:Class="Zhaoxi.PrismRegion.Journal.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:Zhaoxi.PrismRegion.Journal.Views"mc:Ignorable="d" FontSize="20"d:DesignHeight="450" d:DesignWidth="800"><Grid><StackPanel><TextBlock Text="View A" Foreground="Orange" /><Button Content="向后" Command="{Binding GoBackCommand}"/><Button Content="向前" Command="{Binding ForwordCommand}"/></StackPanel></Grid>
</UserControl>

页面的ViewModel继承INavigationAware接口

在OnNavigatedTo方法中取出navigationContext.NavigationService.Journal

journal.GoBack()提供导航回退

public class ViewAViewModel : INavigationAware
{public DelegateCommand GoBackCommand { get; set; }public DelegateCommand ForwordCommand { get; set; }IRegionNavigationJournal journal;public ViewAViewModel(IRegionManager regionManager){GoBackCommand = new DelegateCommand(() =>{if (journal.CanGoBack){journal.GoBack();}});ForwordCommand = new DelegateCommand(() =>{if (journal.CanGoForward){journal.GoForward();}else{regionManager.RequestNavigate("MainRegion", "ViewB");}});}public void OnNavigatedTo(NavigationContext navigationContext){journal = navigationContext.NavigationService.Journal;}public bool IsNavigationTarget(NavigationContext navigationContext){return true;}public void OnNavigatedFrom(NavigationContext navigationContext){}
}

 参照ViewA写ViewB和ViewC

修改对应ViewModel的GoBackCommand与ForwordCommand

public ViewBViewModel(IRegionManager regionManager)
{GoBackCommand = new DelegateCommand(() =>{if (journal.CanGoBack){journal.GoBack();}});ForwordCommand = new DelegateCommand(() =>{if (journal.CanGoForward){journal.GoForward();}else{regionManager.RequestNavigate("MainRegion", "ViewC");}});
}
public ViewCViewModel(IRegionManager regionManager)
{GoBackCommand = new DelegateCommand(() =>{if (journal.CanGoBack){journal.GoBack();}});ForwordCommand = new DelegateCommand(() =>{if (journal.CanGoForward){journal.GoForward();}});
}

运行后实现导航的前进后退

取消导航——IJournalAware

在ViewB的ViewModel中继承IJournalAware接口,并在实现方法中返回false。

public class ViewBViewModel : INavigationAware, IJournalAware
{public DelegateCommand GoBackCommand { get; set; }public DelegateCommand ForwordCommand { get; set; }IRegionNavigationJournal journal;public ViewBViewModel(IRegionManager regionManager){GoBackCommand = new DelegateCommand(() =>{if (journal.CanGoBack){journal.GoBack();}});ForwordCommand = new DelegateCommand(() =>{if (journal.CanGoForward){journal.GoForward();}else{regionManager.RequestNavigate("MainRegion", "ViewC");}});}public void OnNavigatedTo(NavigationContext navigationContext){journal = navigationContext.NavigationService.Journal;}public bool IsNavigationTarget(NavigationContext navigationContext){return true;}public void OnNavigatedFrom(NavigationContext navigationContext){}// IJournalAware的方法实现 public bool PersistInHistory(){return false;}
}

运行后,导航会取消ViewB的导航

来源:https://www.cnblogs.com/ZHIZRL/p/17883434.html

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/66168.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

PbootCMS模板安装与授权方法

为了更清晰地展示 PBootCMS 模板的安装与授权步骤,可以将这些步骤整理成一个表格:步骤 描述 操作1 准备环境 将 PBootCMS 系统文件放入支持 PHP(5.3+)的空间。<br>系统自带完整后台及模板,默认采用 SQLite 数据库,无需额外导入和配置。2 访问后台 访问后台地址:&l…

win11 如何修改hosts文件

相信坚持的力量,日复一日的习惯.

PbootCms后台登陆不显示验证码【阿里云虚拟主机】

问题描述 在使用阿里云虚拟主机部署 PBootCMS 时,后台登录界面不显示验证码图片。这通常是由于阿里云虚拟主机的配置问题导致的。 解决方案登录阿里云控制台 进入虚拟主机管理 进入高级环境设置 编辑 php.ini 文件详细步骤登录阿里云控制台登录阿里云官网:https://www.aliyun…

(三)项目准备工作

前言:虽然Ignition可以在不做任何配置的情况下直接使用,但为了方便以后的操作,我们先准备好数据库,配置网关 1.下载MySQL数据库与jar驱动包 2.安装MySQL数据库 3.配置MySQL数据库配置root密码P@ssw0rd,之后会自动打开MySQL Bench选择默认连接,填入刚才设置的密码即可连接…

将 LLMs 精调至 1.58 比特: 使极端量化变简单

随着大语言模型 (LLMs) 规模和复杂性的增长,寻找减少它们的计算和能耗的方法已成为一个关键挑战。一种流行的解决方案是量化,其中参数的精度从标准的 16 位浮点 (FP16) 或 32 位浮点 (FP32) 降低到 8 位或 4 位等低位格式。虽然这种方法显著减少了内存使用量并加快了计算速度…

WordPress产品分类添加,自动排序插件

效果图如下 目前这个预览菜单这个效果有点问题,但是不影响实际排序,有懂源码的朋友可以自行修改一下,目录结构menu  -assets    menu.cssmenu.jsmenu.php   源码如下menu.php文件<?php /*** Plugin Name: 菜单整理* Description: 将 WooCommerce 产品分类添加…

【VMware VCF】使用 VCF Import Tool 将现有 vSphere 环境导入为 VI 域。rp

VCF Import Tool 工具使用两种方式来帮助客户将现有的 vSphere 或 vSphere + vSAN 环境转变为 VMware Cloud Foundation 环境,分别是转换(Convert)和导入(Import)。之前在这篇(使用 VCF Import Tool 将现有 vSphere 环境转换为管理域。)文章中演示了将现有 vSphere 环境…

SpringBoot+Docker +Nginx 部署前后端项目Hf

部署SpringBoot项目(通关版) 一、概述 使用 java -jar 命令直接部署项目的JAR包和使用Docker制作镜像进行部署是两种常见的部署方式。以下是对这两种方式的概述和简要的优劣势分析: 1.1、使用 java -jar 命令直接部署项目的JAR包 概述:通过 java -jar 直接部署项目的JAR包是…