WPF Stylet可以如何实现导航功能?

前言
本文是学习Stylet中导航Demo的总结,希望对你有所帮助。
Demo所在的位置:

先看一下导航的效果:
首页

通过上面导航到Page 2:

通过Page1导航到Page2:

Stylet是如何实现导航的?
先来看一下页面布局:

一共有ShellView、HeaderView、Page1View与Page2View一共四个View。
ShellView的xaml如下:
<Window x:Class="Stylet.Samples.NavigationController.Pages.ShellView"
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:Stylet.Samples.NavigationController.Pages"
mc:Ignorable="d"
Title="Navigation Controller sample" Height="450" Width="800"
xmlns:s="https://github.com/canton7/Stylet"
d:DataContext="{d:DesignInstance local:ShellViewModel}">
<DockPanel>
<ContentControl DockPanel.Dock="Top" s:View.Model="{Binding HeaderViewModel}"/>
<ContentControl s:View.Model="{Binding ActiveItem}"/>
</DockPanel>
</Window>
页面的上部分通过s:View.Model="{Binding HeaderViewModel}"绑定到了HearView。
下部分通过s:View.Model="{Binding ActiveItem}"绑定到了激活项的View。
这里你可能会感到疑惑,ActiveItem这个属性是哪里来的呢?
ActiveItem这个属性是在ConductorBaseWithActiveItem<T>中定义的:

ShellViewModel继承 Conductor<IScreen>, Conductor<IScreen>继承 ConductorBaseWithActiveItem<T>。
这里你就把ActiveItem理解成导航激活的那个ViewModel就行了,这个例子中要么是Page1ViewModel要么就是Page2ViewModel。
现在来看一下NavigationController:
public class NavigationController : INavigationController
{
private readonly Func<Page1ViewModel> page1ViewModelFactory;
private readonly Func<Page2ViewModel> page2ViewModelFactory;
public INavigationControllerDelegate Delegate { get; set; }
public NavigationController(Func<Page1ViewModel> page1ViewModelFactory, Func<Page2ViewModel> page2ViewModelFactory)
{
this.page1ViewModelFactory = page1ViewModelFactory ?? throw new ArgumentNullException(nameof(page1ViewModelFactory));
this.page2ViewModelFactory = page2ViewModelFactory ?? throw new ArgumentNullException(nameof(page2ViewModelFactory));
}
public void NavigateToPage1()
{
this.Delegate?.NavigateTo(this.page1ViewModelFactory());
}
public void NavigateToPage2(string initiator)
{
Page2ViewModel vm = this.page2ViewModelFactory();
vm.Initiator = initiator;
this.Delegate?.NavigateTo(vm);
}
}
看一下INavigationController:
public interface INavigationController
{
void NavigateToPage1();
void NavigateToPage2(string initiator);
}
首先解决一个疑问,这里为什么使用private readonly Func<Page1ViewModel> page1ViewModelFactory;而不是直接使用Page1ViewModel呢?
我们知道在C#中Func<Page1ViewModel>表示一个没有参数,返回值为Page1ViewModel的委托。
再看看Bootstrapper中的ConfigureIoC方法:

这样写的目的就是不是一开始就将Page1ViewModel与Page2ViewModel注入进来,而是在使用的时候才注入进来。
我们发现在NavigationController中具体实现导航是通过INavigationControllerDelegate接口实现的,让我们再来看看这个接口:
public interface INavigationControllerDelegate
{
void NavigateTo(IScreen screen);
}
回到ShellViewModel,我们发现它实现了这个接口。

来看下它的实现:
public void NavigateTo(IScreen screen)
{
this.ActivateItem(screen);
}
使用的是 Conductor<T>中的ActivateItem方法:

当我们从页面1导航到页面2时:

由于要导航去的Page2ViewModel不是当前的激活项Page1ViewModel,就会来到ChangeActiveItem方法:

关闭之前的激活项,设置新的激活项。
就成功导航到Page2ViewModel了,然后根据Page2ViewModel就会找到Page2View了,这样就成功实现导航功能了。
最后再来看一下有一个循环依赖问题:

这里存在一个循环依赖关系:ShellViewModel -> HeaderViewModel -> NavigationController -> ShellViewModel。
如果直接在NavigationController的构造函数中注入ShellViewModel就会引发这个循环依赖问题。
作者通过在构建 NavigationController 后,再将 ShellViewModel 赋值给它的方式来打破这一循环依赖。
最后
Stylet导航功能的实现主要是通过Conductor<T>实现的。
从作者的这个示例中学习了如何使用Stylet实现一个导航应用,还是学习到了很多知识的,感谢作者的付出!!
WPF Stylet可以如何实现导航功能?的更多相关文章
- ViewModel从未如此清爽 - 轻量级WPF MVVM框架Stylet
Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家. Stylet是受Caliburn Micro项目的启发, 所以借鉴 ...
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(1)
.NET Core 3.0已经发布了,除了一大堆令人激动的功能以外,也增加了对WPF的正式支持, 那么WPF在.NET Core 3.0下的开发体验如何呢? 本文利用了Stylet框架开发.NET C ...
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(4) - 图书列表界面
在前三章中我们完成了登录窗口, 并掌握了使用Conductor来切换窗口, 但这些其实都是在为我们的系统打基础. 而本章中我们就要开始开发系统的核心功能, 即图书管理功能了. 通过本章, 我们会接触到 ...
- WPF优秀组件推荐之Stylet(一)
一.简介 Stylet是基于WPF的一款MVVM组件,虽然WPF本身是自带MVVM功能的,但实现起来不是很方便 ,通过Stylet,用户可以用很少的代码就能享受MVVM带来的舒适体验. 目前Style ...
- WPF优秀组件推荐之Stylet(二)
上一篇文章介绍了Stylet的一些基本功能,本篇将介绍一些深入一点的功能. 依赖注入 在Bootstrapper 类中注入需要的对象: public class Bootstrapper : Boot ...
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(3) - 使用Conductor切换页面
前两章中, 我们已经实现了这个图书管理系统的登录窗口, 并实施了完善的单元测试. 该是时候回过头来关注我们的主窗口了. 一个功能丰富的系统一般会有多个页面, 我们图书管理系统虽然是"简易&q ...
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(2) - 单元测试
上一章中我们完成了一个简单的登录功能, 这一章主要演示如何对Stylet工程中的ViewModel进行单元测试. 回忆一下我们的登录逻辑,主要有以下4点: 当"用户名"或" ...
- 从PRISM开始学WPF
我最近打算学习WPF ,在寻找MVVM框架的时候发现了PRISM,在此之前还从一些博客上了解了其他的MVVM框架,比如浅谈WPF中的MVVM框架--MVVMFoundation 中提到的MVVMFou ...
- 轻量级MVVM框架 Stylet
这两天试了下Stylet框架,这个框架虽然很小,但是功能齐全,简化了很多MVVM的代码,比如Command,对Dialog,MessageBox都有很好的支持. 开源地址 https://github ...
- 从PRISM开始学WPF(一)WPF-更新至Prism7.1
原文:从PRISM开始学WPF(一)WPF-更新至Prism7.1 我最近打算学习WPF ,在寻找MVVM框架的时候发现了PRISM,在此之前还从一些博客上了解了其他的MVVM框架,比如浅谈WPF中的 ...
随机推荐
- 利用堆排序和分治法求解千万级数据排序的Top K问题—百度面试
目录 问题描述 问题解析 第一步:查询次数统计 第二步:找出Top 10 算法一:排序 算法二:部分排序 算法三:堆排序 1.构造初始堆 2.首尾交换,断尾重构 3.迭代执行第二步 算法四:分治法 小 ...
- sublime text 3 c++配置(编译+运行)
之前在网上找了很多配置教程都没成功,要么只能编译,要么只能运行编译好后的exe,没办法一键运行. 方法: 操作方式: 点击**工具,再选编译系统,再选新建编译系统** 然后,把下面的代码,全部复制,并 ...
- windows下大数据开发环境搭建(5)——Hive环境搭建
本文介绍如何在windows下搭建Hive开发环境,主要依赖的环境是Java和Hadoop,其他大部分工作主要是动手配置的工作,按照下面的介绍一步步操作即可完成搭建. 一.所需环境 1.Java:wi ...
- 「Note」CF 套题
最后一次添加的题目:CF1572C CF *2000-*2100 \(\color{blueviolet}{CF771C}\) 非常好题目啊. 首先考虑题目让你求的到底是个什么东西,不难看出 \(f( ...
- Kubernetes控制器-Horizontal Pod Autoscaler(HPA)
Horizontal Pod Autoscaler(HPA) 我们可以通过手动执行kubeclt sacle命令实现Pod的扩缩容,但是这显然不符合Kubernetes的定位目标-自动化和智能化.Ku ...
- Springboot笔记<5>静态资源访问
静态资源访问 静态资源目录 请求进来,先去找Controller看能不能处理.不能处理的所有请求又都交给静态资源处理器.静态资源也找不到则响应404页面.如果静态目录中存在a.png,访问localh ...
- git-intelligence-message 1.3.2 发布了,智能生成、提交git的工具
git-intelligence-message 1.3.2 发布了,这是一次小版本更新.主要内容是可以通过命令查看AI配置信息了. Git Intelligence Message (GIM) 是一 ...
- Review-Gate MCP,让你的 cursor request 次数翻 5 倍
最新资讯: cursor pro 改为无限制,但某些模型(新模型?)依旧限制,看起来是一个黑盒,具体没细说,因此你可以考虑装或者不装本文的 MCP. 另外,本文属于前端社区的一次分享,只是顺带迁移到个 ...
- Rtpengine 全面指南 (mr13.1.1.6):启动参数、配置详解及双网卡SBC部署实例
引言 本文档旨在为 rtpengine (版本 mr13.1.1.6) 用户提供一份详尽的参考指南.内容涵盖 rtpengine 的进程启动参数.rtpengine.conf 配置文件的主要参数说明, ...
- 想要用Altair的仿真软件,记住这个入门级配置
如果你想使用Altair的仿真软件,以下是一些入门级配置的建议. 首先,你需要确保你的计算机满足以下要求: 操作系统:Altair支持多种操作系统,包括Windows.Linux和Mac OS.你需要 ...