Windows 執行階段 8.x 到 UWP 案例研究:QuizGame 範例應用程式
本主題將介紹一個案例研究,說明如何將正常運作的點對點問答遊戲 WinRT 8.1 範例應用程式移植到 Windows 10 通用 Windows 平台 (UWP) 應用程式。
Universal 8.1 應用程式可建置相同應用程式的兩個版本:一個適用於 Windows 8.1 的應用程式套件,另一個適用於 Windows Phone 8.1 的應用程式套件。 QuizGame 的 WinRT 8.1 版本使用通用 Windows 應用程式專案安排,但它採用了不同的方法,並為兩個平台建置了功能不同的應用程式。 Windows 8.1 應用程式套件充當問答遊戲工作階段的主機,而 Windows Phone 8.1 應用程式套件則充當主機的用戶端角色。 問答遊戲工作階段的兩個部分會透過點對點網路進行通訊。
將這兩部分分別針對電腦和手機進行客製化是合理的選擇。 但如果您可以同時在您選擇的任何裝置上執行主機和用戶端,不是更好嗎? 在本案例研究中,我們會將這兩個應用程式移植到 Windows 10,它們將各自建置到一個應用程式套件中,讓使用者可以將其安裝到各種裝置上。
該應用程式使用利用檢視和檢視模型的模式。 如您所見,由於這種分離很徹底,該應用程式的移植過程會非常簡單。
注意 此範例假設您的網路已設定為傳送和接收自訂 UDP 群組多點傳送封包 (大多數家庭網路都是如此,但您的工作網路可能不是)。 此範例也會傳送和接收 TCP 封包。
注意 在 Visual Studio 中開啟 QuizGame10 時,如果看到「需要更新 Visual Studio」訊息,請按照 TargetPlatformVersion 中的步驟操作。
下載
下載 QuizGame Universal 8.1 應用程式。 這是移植之前應用程式的初始狀態。
下載 QuizGame10 Windows 10 應用程式。 這是移植後應用程式的狀態。
WinRT 8.1 解決方案
以下是 QuizGame (我們要移植的應用程式) 看起來的樣子。
在 Windows 上執行的 QuizGame 主機應用程式
在 Windows Phone 上執行的 QuizGame 用戶端應用程式
QuizGame 的逐步使用解說
這是對使用中應用程式的簡短假設說明,但如果您想透過無線網路親自試用該應用程式,它可以提供有用的資訊。
酒吧中正在進行一場有趣的問答遊戲。 酒吧裡有一台所有人都能看到的大電視。 問答遊戲主持人有一台電腦,其輸出會顯示在電視上。 該電腦上正在執行「主機應用程式」。 任何想要參加問答遊戲的人只需在手機或 Surface 上安裝「用戶端應用程式」即可。
主機應用程式處於大廳模式,並顯示在大電視上,該應用程式正在公告它已可供用戶端應用程式連線。 Joan 在她的行動裝置上啟動用戶端應用程式。 她在玩家名稱文字方塊中輸入自己的名字,然後點擊加入遊戲。 主機應用程式透過顯示 Joan 的名字來確認她已加入,而 Joan 的用戶端應用程式則表示正在等待遊戲開始。 接下來,Maxwell 在他的行動裝置上執行相同的步驟。
問答遊戲主持人按一下開始遊戲,主機應用程式會顯示一個問題和可能的答案 (它還會以正常粗細的灰色字體顯示已加入的玩家清單)。 同時,答案也會顯示在已連線用戶端裝置的按鈕上。 Joan 點選其上顯示「1975」答案的按鈕,接著所有按鈕都會進入停用狀態。 在主機應用程式上,Joan 的名字會變成綠色 (並變為粗體),以確認收到她的答案。 Maxwell 也選好了答案。 問答主持人發現所有玩家的名字都變成綠色後,按一下下一個問題。
在這同一個週期中,應用程式會不斷提出問題並取得答案。 當主機應用程式上顯示最後一個問題時,按鈕的內容會變成顯示結果,而不是下一個問題。 點擊顯示結果後,將顯示結果。 按一下返回大廳即可返回遊戲生命週期的開頭,但已加入的玩家仍會保持已加入狀態。 但返回大廳後,就能讓新玩家把握機會加入遊戲,甚至能讓已加入的玩家方便離開 (儘管已加入的玩家可以透過點擊離開遊戲隨時離開)。
本機測試模式
若要在單一電腦上試用應用程式並與其互動,而不是分散到裝置上,您可以在本機測試模式下建立主機應用程式。 這種模式完全不需要使用網路。 相反地,主機應用程式的 UI 會將主機部分顯示在視窗左側,並在右側以垂直堆疊的方式顯示兩種用戶端應用程式 UI 副本 (請注意,在此版本中,本機測試模式 UI 固定為電腦顯示;不適用於小型裝置)。 這些 UI 區段都在同一個應用程式中,透過模擬用戶端通訊器相互通訊,其會模擬原本透過網路進行的互動。
若要啟動本機測試模式,請將 LOCALTESTMODEON (在專案屬性中) 定義為條件式編譯符號,然後重建。
移植到 Windows 10 專案
QuizGame 具有以下部分。
- P2PHelper。 這是一個包含點對點網路邏輯的可移植類別庫。
- QuizGame.Windows。 這個專案可為針對 Windows 8.1 的主機應用程式建置應用程式套件。
- QuizGame.WindowsPhone。 這個專案可為針對 Windows Phone 8.1 的用戶端應用程式建置應用程式套件。
- QuizGame.Shared。 此專案包含原始程式碼、標記檔案以及其他資產和資源,這些內容也可由其他兩個專案使用。
對於本案例研究,我們會根據如果您有 Universal 8.1 應用程式中所述提供一些常用選項,以及支援哪些裝置。
根據這些選項,我們將 QuizGame.Windows 移植到名為 QuizGameHost 的新 Windows 10 專案。 並且,我們會將 QuizGame.WindowsPhone 移植到名為 QuizGameClient 的新 Windows 10 專案。 這些專案將面向通用裝置系列,因此它們可以在任何裝置上執行。 然後我們將 QuizGame.Shared 來源檔案等保留在其資料夾中,並將這些共用檔案連結到兩個新專案中。 就像之前一樣,我們將把所有內容保留在一個解決方案中,並將其命名為 QuizGame10。
QuizGame10 解決方案
- 建立一個新解決方案 (新專案>其他專案類型>Visual Studio 解決方案),並將其命名為 QuizGame10。
P2PHelper
- 在解決方案中,建立一個新的 Windows 10 類別庫專案 (新專案>Windows 通用>類別庫 (Windows 通用)),並將其命名為 P2PHelper。
- 從新專案中刪除 Class1.cs。
- 將 P2PSession.cs、P2PSessionClient.cs 和 P2PSessionHost.cs 複製到新專案的資料夾中,並將複製的檔案加入新專案中。
- 該專案將隨即建置,而無需進一步變更。
共用的檔案
- 將資料夾 Common、Model、View 和 ViewModel 從 \QuizGame.Shared\ 複製到 \QuizGame10\。
- 說到磁碟上的共用資料夾時,我們指的是 Common、Model、View 和 ViewModel。
QuizGameHost
- 建立一個新的 Windows 10 應用程式專案 (新增>新專案>Windows 通用>空白應用程式 (Windows 通用)),並將其命名為 QuizGameHost。
- 新增 P2PHelper 的參考 (新增參考>專案>解決方案>P2PHelper)。
- 在方案總管中,為磁碟上的每個共用資料夾建立一個新資料夾。 依序以右鍵點擊剛剛建立的每個資料夾,然後按一下新增>現有項目,並向上瀏覽至資料夾。 開啟相應的共用資料夾,選擇所有檔案,然後按一下新增為連結。
- 將 MainPage.xaml 從 \QuizGame.Windows\ 複製到 \QuizGameHost\,並將命名空間變更為 QuizGameHost。
- 將 App.xaml 從 \QuizGame.Shared\ 複製到 \QuizGameHost\,並將命名空間變更為 QuizGameHost。
- 我們不會覆寫 app.xaml.cs,而是將版本保留在新專案中,並只對其進行一項有針對性的變更,以支援本地測試模式。 在 app.xaml.cs 中,取代以下這行程式碼:
rootFrame.Navigate(typeof(MainPage), e.Arguments);
取代為這個:
#if LOCALTESTMODEON
rootFrame.Navigate(typeof(TestView), e.Arguments);
#else
rootFrame.Navigate(typeof(MainPage), e.Arguments);
#endif
- 在屬性>建置>條件式編譯符號中,新增 LOCALTESTMODEON。
- 現在您可以回到新增至 app.xaml.cs 的程式碼,並解析 TestView 類型。
- 在 package.appxmanifest 中,將功能名稱從 internetClient 變更為 internetClientServer。
QuizGameClient
- 建立一個新的 Windows 10 應用程式專案 (新增>新專案>Windows 通用>空白應用程式 (Windows 通用)),並將其命名為 QuizGameClient。
- 新增 P2PHelper 的參考 (新增參考>專案>解決方案>P2PHelper)。
- 在方案總管中,為磁碟上的每個共用資料夾建立一個新資料夾。 依序以右鍵點擊剛剛建立的每個資料夾,然後按一下新增>現有項目,並向上瀏覽至資料夾。 開啟相應的共用資料夾,選擇所有檔案,然後按一下新增為連結。
- 將 MainPage.xaml 從 \QuizGame.WindowsPhone\ 複製到 \QuizGameClient\,並將命名空間變更為 QuizGameClient。
- 將 App.xaml 從 \QuizGame.Shared\ 複製到 \QuizGameClient\,並將命名空間變更為 QuizGameClient。
- 在 package.appxmanifest 中,將功能名稱從 internetClient 變更為 internetClientServer。
您現在可以建置並執行應用程式了。
調適型 UI
當應用程式在寬視窗中執行階段,QuizGameHost Windows 10 應用程式看起來沒什麼問題 (這只在大螢幕裝置上可行)。 但是,當應用程式的視窗很窄時 (這種情況通常發生在小型裝置上,但也可能發生在大型裝置上),UI 會被擠壓得難以閱讀。
我們可以使用調適型「視覺狀態管理器」功能來解決這個問題,方法就如同我們在案例研究:Bookstore2 中說過的那樣。 首先,設定視覺元素的屬性,以便預設 UI 處於窄型狀態。 這些變更都發生在 \View\HostView.xaml 中。
- 在主方格中,將第一個 RowDefinition 的高度從「140」變更為「自動」。
- 在包含名為
pageTitle
的 TextBlock 方格上,設定x:Name="pageTitleGrid"
和Height="60"
。 前兩個步驟是為了讓我們可以在視覺狀態下透過設定器有效控制 RowDefinition 的高度。 - 在
pageTitle
上,設定Margin="-30,0,0,0"
。 - 在註解
<!-- Content -->
指示的方格上,設定x:Name="contentGrid"
和Margin="-18,12,0,0"
。 - 在緊鄰註解
<!-- Options -->
上方的 TextBlock 上設定Margin="0,0,0,24"
。 - 在預設的 TextBlock 樣式 (檔案中的第一個資源) 中,將 FontSize 設定器的值變更為「15」。
- 在
OptionContentControlStyle
中,將 FontSize 設定器的值變更為「20」。 這一步驟和上一步驟將提供一個良好的類型斜坡,其可以在所有裝置上正常運作。 這些尺寸比我們在 Windows 8.1 應用程式中使用的「30」要靈活得多。 - 最後,將適當的「視覺狀態管理器」標記新增至根方格。
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="WideState">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="548"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="pageTitleGrid.Height" Value="140"/>
<Setter Target="pageTitle.Margin" Value="0,0,30,40"/>
<Setter Target="contentGrid.Margin" Value="40,40,0,0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
通用樣式
您會發現在 Windows 10 中,按鈕的範本中沒有相同的觸控目標邊框間距。 兩個小改變可以解決這個問題。 首先,將此標記加入到 QuizGameHost 和 QuizGameClient 中的 app.xaml 中。
<Style TargetType="Button">
<Setter Property="Margin" Value="12"/>
</Style>
其次,將此設定器新增至 \View\ClientView.xaml 中的 OptionButtonStyle
。
<Setter Property="Margin" Value="6"/>
經過最後的調整後,該應用程式的行為和外觀將與移植之前一樣,更棒的是它現在可以在任何地方執行。
結論
我們在本案例研究中移植的應用程式相對複雜,涉及多個專案、一個類別庫以及相當大量的程式碼和使用者介面。 即便如此,移植過程還是滿簡單的。 之所以能如此輕鬆地移植,部分原因在於 Windows 10 開發人員平台與 Windows 8.1 和 Windows Phone 8.1 平台之間具有相似性。 另一部分原因是由於原始應用程式在設計時,就將模型、檢視模型和檢視分開。