当前位置: 首页 > news >正文

从PRISM开始学WPF(八)导航Navigation?

原文: 从PRISM开始学WPF(八)导航Navigation?

0x6Navigation

Basic Navigation

Prism中的Navigation提供了一种类似导航的功能,他可以根据用户的输入,来刷新UI。

先看一个最简单的例子,通过按钮来导航到一个视图,在这里,视图被注册为Navication。

        public void Initialize()
        {
            _container.RegisterTypeForNavigation<ViewA>();
            _container.RegisterTypeForNavigation<ViewB>();
        }

Shell 视图中设置两个Button并且绑定下面这个带参数的命令:

        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);
        }
    <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="ContentRegion" Margin="5"  />
    </DockPanel>

RegionManager通过RequestNavigate方法来获取已经注册的Navigation并且绑定到Region上去。

当需要根据调用结果来处理一些事情,可以使用下面这个方法:

void RequestNavigate(string regionName, string source, Action<NavigationResult> navigationCallback);

当然,上面这个方法是在Shell中调用的,但,有些时候,我们需要View或者ViewModel也参与到Navigation中来,比如当你Request一个Navigation的时候,希望navigation本身显示一些信息,为此 Prism为我们提供了一个INavigationAware 接口。

    //
    // Summary:
    //     Provides a way for objects involved in navigation to be notified of navigation
    //     activities.
    public interface INavigationAware
    {
        //
        // Summary:
        //     Called to determine if this instance can handle the navigation request.
        //
        // Parameters:
        //   navigationContext:
        //     The navigation context.
        //
        // Returns:
        //     true if this instance accepts the navigation request; otherwise, false.
        bool IsNavigationTarget(NavigationContext navigationContext);
        //
        // Summary:
        //     Called when the implementer is being navigated away from.
        //
        // Parameters:
        //   navigationContext:
        //     The navigation context.
        void OnNavigatedFrom(NavigationContext navigationContext);
        //
        // Summary:
        //     Called when the implementer has been navigated to.
        //
        // Parameters:
        //   navigationContext:
        //     The navigation context.
        void OnNavigatedTo(NavigationContext navigationContext);
    }

如果想要Navigation的目标也参与到Navigation的过程当中,只需要让你的viewmodel实现这个接口,然后在这些方法里编写你的代码就可以了。
IsNavigationTarget方法设置了是否被允许设置为导航的目标,当他的返回值为Fasle的时候,将不会被“导航”到它。

19-NavigationParticipation的例子中,Region的目标是:

        <TabControl prism:RegionManager.RegionName="ContentRegion" Margin="5"  />

TabControl在设置为Region的时候,加载View时会自动创建Page来存放View,如果“导航”到同一个View他会在Page中找到他,并且显示出来。但如果IsNavigationTarget返回False的话,就不会显示之前的Page而是创建了一个新的Page来加载View。

PassingParameters带参数的导航

使用Navigation的时候,将数据源带到新的NavigationTarget中去,然后Target应用这些数据。这将使用到navigation的NavigationContext参数:

        private void PersonSelected(Person person)
        {
            var parameters = new NavigationParameters();
            parameters.Add("person", person);

            if (person != null)
                _regionManager.RequestNavigate("PersonDetailsRegion", "PersonDetail", parameters);
        }

在Target的OnNavigatedTo方法中使用:


        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            var person = navigationContext.Parameters["person"] as Person;
            if (person != null)
                SelectedPerson = person;
        }

当导航变更的时候你需要一些提示框,需要实现IConfirmNavigationRequest
他有一个ConfirmNavigationRequest方法来进行一些判断。

在上面的例子中,我们在view之间跳转的时候,viewA 和viewB是被缓存的,但是有时候,我们跳转到B的时候想要销毁A,怎么来做呢?
在View或ViewModel上实现IRegionMemberLifetime接口,并将KeepAlive属性的值设置为false。

journal

journal 实现一种类似浏览器前进后退按钮一样的效果,当一个region 有多个view的时候,他会自动记录view的加载顺序,然后在view之间来回切换。
Prism中是通过IRegionNavigationJournal来实现的,在视图加载时,讲道理,可以无限级前进和后退的,我自己在官方的例子上加了一个视图也完美运行。

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            _journal = navigationContext.NavigationService.Journal;
        }

然后使用 :

_journal.GoBack();

或者

_journal.GoForward();

相关文章:

  • 手把手教你将单机游戏改造成对战网游(附详细教程)
  • P2264 情书
  • Spring Boot的@Service和@Autowired和@ComponentScan注解
  • 两个变量交换的四种方法(Java)
  • 分布式消息队列ActiveMQ+Spring整合
  • Vue2.x学习三:事件处理生命周期钩子
  • MySQL的prompt不生效的问题
  • Django之ModelForm(二)-----ModelForm组件
  • Lua使用总结
  • Python模块-threading模块
  • xtrabackup 备份原理
  • tkinter简单打开网址 + 执行系统命令
  • flask学习笔记之flask-migrate
  • 项目实战 (规范、轮子、学习案例) - iOS
  • iOS中类、元类、isa详解
  • 深入了解以太坊
  • 《深入 React 技术栈》
  • 2017届校招提前批面试回顾
  • docker容器内的网络抓包
  • extract-text-webpack-plugin用法
  • javascript 总结(常用工具类的封装)
  • MySQL QA
  • MySQL数据库运维之数据恢复
  • React的组件模式
  • Spring-boot 启动时碰到的错误
  • ucore操作系统实验笔记 - 重新理解中断
  • 关于 Cirru Editor 存储格式
  • 关于extract.autodesk.io的一些说明
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 入门到放弃node系列之Hello Word篇
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • #HarmonyOS:Web组件的使用
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (十三)Maven插件解析运行机制
  • (转)Sublime Text3配置Lua运行环境
  • (转)一些感悟
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .net 调用php,php 调用.net com组件 --
  • .net 后台导出excel ,word
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • :O)修改linux硬件时间
  • [<死锁专题>]
  • [bzoj1324]Exca王者之剑_最小割
  • [BZOJ3223]文艺平衡树
  • [C#]winform部署yolov5-onnx模型
  • [C++] cout、wcout无法正常输出中文字符问题的深入调查(1):各种编译器测试
  • [C++]类和对象【下】
  • [CareerCup] 6.1 Find Heavy Bottle 寻找重瓶子