WPF MVVM框架------ Prism中的区域和导航(二)
接着上一节,记录导航功能
准备工作
- 1. 在ViewModels中新建两个视图对应的ViewModel类(RegionFirstViewModel.cs和RegionSecondViewModel.cs),如图所示
- 2. 将视图与对应的ViewModel绑定
打开 App.xaml.cs 在重写的方法RegisterTypes中进行上下文对应
public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve<RegionManageView>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterForNavigation<RegionFirstView, RegionFirstViewModel>(); containerRegistry.RegisterForNavigation<RegionSecondView, RegionSecondViewModel>(); } }
实现对应的ViewModel
1.RegionFirstViewModel
因为需要将内容显示在界面上,实现通知效果,所以该类需要继承BindableBase,当我们导航到该界面并且想要带一些参数进来,或者想要阻拦当页面跳转到其他页面时,还以要实现IConfirmNavigationRequest接口
1.1 创建一个Name属性,用于显示传递的参数,需要通知到界面上,所以要调用 RaisePropertyChanged()方法,
private string _name; public string Name { get { return _name; } set { _name = value; RaisePropertyChanged(); } }
1.2 继承IConfirmNavigationRequest,需要实现方法
public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } public void OnNavigatedFrom(NavigationContext navigationContext) { Uri uri = navigationContext.Uri; } public void OnNavigatedTo(NavigationContext navigationContext) { Name = navigationContext.Parameters["Name"]?.ToString();//获取传递的参数 } public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback) { bool isOk = false; if (MessageBox.Show("确定跳转吗?", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { isOk = true; } continuationCallback(isOk); }
方法 public void IsNavigationTarget(NavigationContext navigationContext):
表示是否重用该实例,返回false时,将会重新new一个新的实例出来,若返回true,则重用原来的实例
方法 public void OnNavigatedFrom(NavigationContext navigationContext):
当要导航到其他页面之前,会执行该方法,离开该页面之前想要做的事情可以放在该页面 ,参数navigationContext中包含即将导航到的目标页面Uri
方法 public void OnNavigatedTo(NavigationContext navigationContext):
导航到该页面时,会直接进入该方法,可以从navigationContext的Parameters中拿到传递过来的数据,Parameters是以键值对的方式传递参数的,所以可以按照上面的方法获取值
方法 public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback):
当要导航到其他页面时,会首先进入该方法,在这个方法中可以进行拦截或者说是给一个再次确认的机会,调用委托传入true,则可以导航,传入false时则会阻止导航到其他页面
1.3 RegionFirstViewModel 完整代码
public class RegionFirstViewModel : BindableBase, IConfirmNavigationRequest { private string _name; public string Name { get { return _name; } set { _name = value; RaisePropertyChanged(); } } public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } public void OnNavigatedFrom(NavigationContext navigationContext) { Uri uri = navigationContext.Uri; } public void OnNavigatedTo(NavigationContext navigationContext) { Name = navigationContext.Parameters["Name"]?.ToString();//获取传递的参数 } public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback) { bool result = false; if (MessageBox.Show("确定跳转吗?", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { result = true; } continuationCallback(result); } }
2. RegionSecondViewModel
public class RegionSecondViewModel : INavigationAware { public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } public void OnNavigatedFrom(NavigationContext navigationContext) { } public void OnNavigatedTo(NavigationContext navigationContext) { } }
3. 接口 IConfirmNavigationRequest与INavigationAware
其实IConfirmNavigationRequest也继承了INavigationAware,只是IConfirmNavigationRequest多了一个确认导航到其他页面的方法。可以进行再次确认
传递参数以及记录导航
1.修改主页面
打开主窗体 RegionManageView ,添加两个按钮(向前导航和向后导航),并绑定GoForwardCommand和GoBackCommand
<Button Height="25" Content="GoForward" Command="{Binding GoForwardCommand}" CommandParameter="RegionSecondView" /> <Button Height="25" Content="GoBack" Command="{Binding GoBackCommand}" CommandParameter="RegionSecondView" />
2. 传递参数和记录导航
声明一个字段来保存导航记录 private IRegionNavigationJournal journal;
修改private void DoOpenRegionCommand(string obj)方法 其中keyValuePairs就是传递的参数,journal = callBack.Context.NavigationService.Journal则是导航记录
private void DoOpenRegionCommand(string obj) { NavigationParameters keyValuePairs = new() { { "Name", obj } }; regionManager.Regions["MainContent"].RequestNavigate(obj, callBack => { if ((bool)callBack.Result) { journal = callBack.Context.NavigationService.Journal; } }, keyValuePairs); }
3. 实现向前导航和向后导航命令
private void DoGoForwardCommand() { journal?.GoForward(); } private void DoGoBackCommand() { journal?.GoBack(); }
4. 完整主窗体代码
RegionManageView.xalm
<Window x:Class="MvvmBase.PrismDemo.Views.RegionManageView" 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:MvvmBase.PrismDemo.Views" xmlns:prism="http://prismlibrary.com/" mc:Ignorable="d" prism:ViewModelLocator.AutoWireViewModel="True" Title="RegionManageView" Height="450" Width="800"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <StackPanel Width="150"> <Button Height="25" Content="OpenRegionFirstView" Command="{Binding OpenRegionCommand}" CommandParameter="RegionFirstView" /> <Button Height="25" Content="OpenRegionSecondView" Command="{Binding OpenRegionCommand}" CommandParameter="RegionSecondView" /> <Button Height="25" Content="CloseRegionFirstView" Command="{Binding CloseRegionCommand}" CommandParameter="RegionFirstView" /> <Button Height="25" Content="CloseRegionSecondView" Command="{Binding CloseRegionCommand}" CommandParameter="RegionSecondView" /> <Button Height="25" Content="GoForward" Command="{Binding GoForwardCommand}" CommandParameter="RegionSecondView" /> <Button Height="25" Content="GoBack" Command="{Binding GoBackCommand}" CommandParameter="RegionSecondView" /> </StackPanel> <ContentControl Grid.Column="1" prism:RegionManager.RegionName="MainContent" /> </Grid> </Window>
RegionManageViewModel.cs
public class RegionManageViewModel : BindableBase { private readonly IRegionManager regionManager; private IRegionNavigationJournal journal; public DelegateCommand<string> OpenRegionCommand { get; private set; } public DelegateCommand<string> CloseRegionCommand { get; private set; } public DelegateCommand GoForwardCommand { get; private set; } public DelegateCommand GoBackCommand { get; private set; } public RegionManageViewModel(IRegionManager regionManager) { OpenRegionCommand = new DelegateCommand<string>(DoOpenRegionCommand); CloseRegionCommand = new DelegateCommand<string>(DoCloseRegionCommand); GoForwardCommand = new DelegateCommand(DoGoForwardCommand); GoBackCommand = new DelegateCommand(DoGoBackCommand); this.regionManager = regionManager; } private void DoGoForwardCommand() { journal?.GoForward(); } private void DoGoBackCommand() { journal?.GoBack(); } private void DoCloseRegionCommand(string obj) { var views = regionManager.Regions["MainContent"]; var view = views.Views.FirstOrDefault(it => it.GetType().Name == obj); if (view != default) { views.Remove(view); } } private void DoOpenRegionCommand(string obj) { NavigationParameters keyValuePairs = new() { { "Name", obj } }; regionManager.Regions["MainContent"].RequestNavigate(obj, callBack => { if ((bool)callBack.Result) { journal = callBack.Context.NavigationService.Journal; } }, keyValuePairs); } }
Parameters
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律