前兩章中, 咱們已經實現了這個圖書管理系統的登陸窗口, 並實施了完善的單元測試. 該是時候回過頭來關注咱們的主窗口了.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~