原文 了解 UWP 視圖的概念,讓 UWP 應用顯示多個視窗(多視圖) UWP 應用多是一個視窗完成所有業務的,事實上我也推薦使用這種單一視窗的方式。不過,總有一些特别的情況下我們需要用到不止一個視窗,那麼 UWP 中如何使用多視窗呢?
本文内容
多視窗在傳統 Win32 的開發當中是司空見慣的事兒了,不過我個人非常不喜歡,因為 Windows 系統上的多視窗太多坑。以下是我以前寫的關于傳統多視窗開發中的一些坑(除此之外還有更多):
使用多視窗的原因很簡單 —— 允許使用者多任務處理。從這個角度來說,傳統 Win32 使用“模态”多視窗的方式簡直是低效的同時還帶來 Bug!
微軟官方文檔中列舉了一些例子:例如一邊寫郵件一邊參考以往的郵件;一邊看正在播放的音樂一邊浏覽播放清單;一次性打開多份文章然後稍後一起閱讀等。
在學習如何編寫 UWP 多視窗之前,我們需要了解一些 UWP 視圖(View)的概念。
在
CoreApplication/Application、CoreWindow/Window 之間的差別一文中,我描述了 UWP 視圖的一些概念:
為了了解 UWP 的啟動流程,我從零開始建立了一個 UWP 程式管理一個 UWP 應用中的所有視圖(View),而
CoreApplication
直接管理的視圖是
CoreApplication
;也就是說,UWP 應用
CoreApplicationView
管理所有的應用視圖
CoreApplication
。而一個
CoreApplicationView
包含一個視窗和一個線程排程模型,即
CoreApplicationView
和
CoreWindow
。
CoreDispatcher
就是我們所了解的視窗。為了友善使用,
CoreWindow
類型封裝了這個
Windows.UI.XAML.Window
CoreWindow
是基于消息循環的線程排程模型,正是因為有了消息循環,是以此視窗才能一直顯示而不被銷毀。
CoreDispatcher
一文中,我們也能體會到
CoreApplication
CoreWindow
之間的關系,了解消息循環在應用中的作用。
在了解到 UWP 視圖的概念之後,嚴格意義上說,這一節的标題應該叫做 “UWP 多視圖”。
我畫了一個思維導圖來描述它們之間的關系。
CoreApplication
有靜态方法
CreateNewView
,調用後能夠建立新的
CoreApplicationView
,這包含一個完整的
CoreWindow
CoreDispatcher
建立并顯示一個新
CoreApplicationView
的代碼如下:
private async void OnLoaded(object sender, RoutedEventArgs e)
{
// 建立一個 CoreApplicationView,即新的應用視圖。
var applicationView = CoreApplication.CreateNewView();
// 一個應用視圖有自己的 Id,稍後我們建立應用視圖的時候,需要記錄這個 Id。
int newViewId = 0;
// 使用新應用視圖的 CoreDispatcher 線程排程模型來執行新視圖中的操作。
await applicationView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// 在新的應用視圖中,我們将新的視窗内容設定為 ThePageInNewView 頁面。
Frame frame = new Frame();
frame.Navigate(typeof(ThePageInNewView), null);
Window.Current.Content = frame;
Window.Current.Activate();
// 記錄新應用視圖的 Id,這樣才能稍後切換。
newViewId = ApplicationView.GetForCurrentView().Id;
});
// 使用剛剛記錄的新應用視圖 Id 顯示新的應用視圖。
var viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
}
建立完後的效果如下圖:
我們平時開發 UWP 應用的時候很少去關心
CoreApplicationView
,因為預設情況下 UWP 能為我們做很多管理應用視圖的工作。
CoreApplication
有一個
MainView
屬性,即我們一開始運作 UWP 應用時的那個應用視圖。如果我們有不止一個應用視圖顯示出來,那麼這時點選主視窗的關閉按鈕将不再是關閉,而是隐藏。如果要關閉,需要調用
Application.Exit
CoreApplication
有
Views
屬性儲存所有的
CoreApplicationView
,我們可以使用此集合來管理多個視圖。使用
ApplicationViewSwitcher.SwitchAsync
并傳入視圖 Id 可以切換視圖的顯示。
await ApplicationViewSwitcher.SwitchAsync(viewIdToShow);
本文會經常更新,請閱讀原文:
https://walterlv.com/post/show-multiple-views-for-an-uwp-app.html,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。