前两章中, 咱们已经实现了这个图书管理系统的登陆窗口, 并实施了完善的单元测试. 该是时候回过头来关注咱们的主窗口了.html
一个功能丰富的系统通常会有多个页面, 咱们图书管理系统虽然是"简易"的, 可是一样也有多个页面. 因此这一章中, 咱们来学习如何使用Stylet的Conductor来管理页面的切换.git
事实上, 第一章使用的
IWindowManager.ShowDialog
弹出的登陆窗口也可视为一个页面. 可是据个人我的经验, 我更推荐将全部页面放在一个窗口中, 这样更方便实施MVVM. 这章事后,你可尝试使用Conductor来显示登陆页面.github
Conductor翻译过来是指挥的意思, 在Stylet中Conductor就是用来指挥各个ViewModel的, 由于通常在MVVM中ViewModel表明一个页面, 因此Conductor经过管理ViewModel来实现页面的状态的管理. Stylet内置了多种Conductor, 适用于不一样的使用场景, 这里作一个简要的介绍:shell
Conductor | 使用场景 |
---|---|
Conductor<T> |
最简单的Conductor, 只管理一个页面 |
Conductor<T>.Collection.OneActive |
管理多个页面, 但只显示其中的一个. 最典型场景如一个TabControl控件 |
Conductor<T>.Collection.AllActive |
管理多个页面, 而且所有显示. 典型场景如一个ItemControl控件 |
Conductor<T>.StackNavigation |
管理多个页面, 只显示其中一个, 但保留了以前显示页面的历史可用于回退. 典型场景如一个向导页面, 容许用户经过"上一步", "下一步"切换 |
更多关于Conductor的信息, 可参见Stylet的官方WIKI: Screens and Conductorsapp
在本章中, 咱们想要显示两个页面: "首页"和"图书"页面, 由于在同一时间只会显示其中一个, 因此使用Conductor<T>
就能够了. 下面就开始咱们的CODING工做:ide
在Page文件夹中新建一个名为"Home"的文件夹, 并新建一个C#类: HomeViewModel
和一个UserControl: HomeView
, 用来显示咱们系统的首页.单元测试
将HomeViewModel
的基类设置为Screen
:学习
public class HomeViewModel : Screen { }
由于Home中没有任何逻辑, 因此不须要任何其余代码.测试
在HomeView
的XAML中增长如下XAML代码:翻译
<UserControl x:Class="StyletBookStore.Pages.Home.HomeView" ... > <Grid> <TextBlock FontSize="30" HorizontalAlignment="Center" VerticalAlignment="Center"> 欢迎使用简易图书管理系统 </TextBlock> </Grid> </UserControl>
将ShellViewModel
的基类改成Conductor<Screen>
:
public class ShellViewModel : Conductor<Screen> { ... }
这样ShellViewModel
就变成了一个可管理单一页面的Conductor了, 并且每一个页面都须要是Screen
的子类.
由于咱们将全部显示部分放在各自的页面中, 因此将ShellView
中<Window>...</Window>
中的XAML彻底删除, 并替换为如下代码.
<Window x:Class="StyletBookStore.Pages.ShellView" ... Title="简易图书管理系统"> <ContentControl s:View.Model="{Binding ActiveItem}"/> </Window>
Title
设置为咱们的系统名字: "简易图书管理系统"增长一个ContentControl
用来显示页面内容.
s:View.Model
是Stylet提供的附加属性, 用来为View绑定ModelActiveItem
是Conductor<T>
的一个属性, 就是该Conductor的当前的页面. 由于ShellViewModel
继承了Conductor<T>
, 因此在ShellView
中能够绑定该属性.若是你如今启动程序, 会发现程序能够正常启动, 可是Shell中不会显示任何内容. 这是由于咱们未给ShellViewModel
这个Conductor设置ActiveItem.
在ShellViewModel
的OnViewLoaded
方法的开始位置, 增长如下代码, 用来在程序启动时就显示首页.
protected override void OnViewLoaded() { // 显示首页 var homeViewModel = _container.Get<HomeViewModel>(); ActivateItem(homeViewModel); // 显示登陆窗口 ... }
ActivateItem
方法是Condocutor<T>
中提供的方法.用一个新的ViewModel实例替换当前的ActiveItem
,激活新的页面并关闭旧的. 咱们使用该方法便可实现页面的切换.
再次启动程序, 确认首页已经能正常显示了:
Page文件夹中新建一个名为"Books"的文件夹, 并新建一个C#类: IndexViewModel
和一个UserControl: IndexView
, 用来显示图书列表页面:
要点以下:
IndexViewModel
的基类设置为Screen
IndexView
中增长一个TextBlock
用来(暂时)标识这是图书页面: <TextBlock Text="IndexView"/>
一样, 在ShellViewModel
的OnViewLoaded
方法的末尾位置, 增长如下代码, 用来在登陆成功后, 切换到图书页面:
protected override void OnViewLoaded() { // 显示首页 var homeViewModel = _container.Get<HomeViewModel>(); ActivateItem(homeViewModel); // 显示登陆窗口 ... // 显示图书 var indexViewModel = _container.Get<IndexViewModel>(); ActivateItem(indexViewModel); }
再次使用ActivateItem
方法, 将图书的ViewModel切换进来. 再次启动程序, 确认当登陆成功后, 主窗口的页面会切换到图书页面.(目前只显示一个IndeView, 咱们会在下一章完善该页面的功能)
本篇到此为止, 但愿朋友们能多多留言, 鼓励我能继承写下去. 源码托管在GITHUB上.
Happy Coding~