Share via


Windows 執行階段 8.x 到 UWP 案例研究:Bookstore2

本案例研究以 Bookstore1 中提供的資訊為基礎,其以 Universal 8.1 應用程式開頭,並在 SemanticZoom 控制項中顯示分組資料。 在檢視模型中,作者類別的每個執行個體代表該作者撰寫的書籍群組,在 SemanticZoom 中,我們可以查看依照作者分組的書籍清單,也可以縮小以查看作者的捷徑清單。 跳躍清單的瀏覽方式比捲動書籍清單更快。 我們會逐步解說將應用程式移植到 Windows 10 通用 Windows 平台 (UWP) 應用程式的步驟。

注意 在 Visual Studio 中開啟 Bookstore2Universal_10 時,如果看到「需要更新 Visual Studio」訊息,請按照 TargetPlatformVersion 中的步驟操作。

下載

下載 Bookstore2_81 Universal 8.1 應用程式

下載 Bookstore2Universal_10 Windows 10 應用程式

Universal 8.1 應用程式

以下是我們要移植的應用程式 Bookstore2_81 的樣子。 這是一個水平捲動 (在 Windows Phone 上垂直捲動) SemanticZoom,其中顯示書籍依作者分組。 您可以縮小至捷徑清單,然後可以從那裡瀏覽回任意群組。 該應用程式分為兩個主要部分:一個是提供分組資料來源的檢視模型,一個是繫結到該檢視模型的使用者介面。 如我們所見,這兩個部分都可以輕鬆地從 WinRT 8.1 技術移植到 Windows 10。

bookstore2-81 on windows, zoomed-in view

Windows 上的 Bookstore2_81,放大檢視

bookstore2-81 on windows, zoomed-out view

Windows 上的 Bookstore2_81,縮小檢視

bookstore2-81 on windows phone, zoomed-in view

Windows Phone 上的 Bookstore2_81,放大檢視

bookstore2-81 on windows phone, zoomed-out view

Windows Phone 上的 Bookstore2_81,縮小檢視

移植到 Windows 10 專案

Bookstore2_81 解決方案屬於 8.1 Universal App 專案。 Bookstore2_81.Windows 專案可建置適用於 Windows 8.1 的應用程式套件,Bookstore2_81.WindowsPhone 專案可建置適用於 Windows Phone 8.1 的應用程式套件。 專案 Bookstore2_81.Shared 包含原始程式碼、標記檔案以及其他資產和資源,這些內容也可由其他兩個專案使用。

就像先前的案例研究一樣,我們將採用的選項 (如果您有 Universal 8.1 應用程式中描述的選項) 是將共用專案的內容移植到面向通用裝置系列的 Windows 10。

首先是建立一個新的空白應用程式 (Windows 通用) 專案。 將其命名為 Bookstore2Universal_10。 以下是要從 Bookstore2_81 複製到 Bookstore2Universal_10 的檔案。

從共用專案

  • 複製包含書籍封面影像 PNG 檔案的資料夾 (該資料夾為 \Assets\CoverImages)。 複製資料夾後,在方案總管中,請確認顯示所有檔案已開啟。 在您複製的資料夾上按右鍵,然後按一下加入至專案。 該命令就是所謂的在專案中「加入」檔案或資料夾。 每次複製檔案或資料夾時,在方案總管中按一下重新整理,然後將該檔案或資料夾加入專案中。 對於您要在目的地中取代的檔案,無需執行此操作。
  • 複製包含檢視模型來源檔案的資料夾 (該資料夾為 \ViewModel)。
  • 複製 MainPage.xaml,然後取代目的地中的檔案。

從 Windows 專案

  • 複製 BookstoreStyles.xaml。 我們將使用此檔案作為起點,這是個不錯的選擇,因為此檔案中的所有資源索引鍵都將在 Windows 10 應用程式中解析;而對等 WindowsPhone 檔案中的某些索引鍵則不會。
  • 複製 SeZoUC.xaml 和 SeZoUC.xaml.cs。 我們將從該檢視的 Windows 版本開始,其適用於寬視窗,之後我們要進行調整,使其符合較小的視窗,從而適用於較小的裝置。

編輯剛剛複製的原始程式碼和標記檔案,將對 Bookstore2_81 命名空間的所有參考變更為 Bookstore2Universal_10。 若想快速執行此動作,可使用取代檔案功能。 檢視模型和其他命令式程式碼都不需要變更程式碼。 但是,為了讓您能更輕鬆地查看正在執行的應用程式版本,請將 Bookstore2Universal_10.BookstoreViewModel.AppName 屬性傳回的值從「Bookstore2_81」變更為「BOOKSTORE2UNIVERSAL_10」。

現在,您可以建置並執行了。 以下是尚未移植到 Windows 10 的新 UWP 應用程式外觀。

the windows 10 app with initial source code changes running on a desktop device, zoomed-in view

在桌面裝置上執行且已變更初始原始程式碼的 Windows 10 應用程式,放大檢視

the windows 10 app with initial source code changes running on a desktop device, zoomed-out view

在桌面裝置上執行且已變更初始原始程式碼的 Windows 10 應用程式,縮小檢視

檢視模型以及放大和縮小的檢視可以正確地協同運作,儘管存在一些問題使其有點難以看到。 其中一個問題是 SemanticZoom 不會捲動。 這是因為在 Windows 10 中,GridView 的預設樣式導致其垂直配置 (Windows 10 設計指南建議在新應用程式和移植應用程式中使用這種方式)。 但是,我們從 Bookstore2_81 專案 (專為 8.1 應用程式設計) 複製的自訂專案面板範本的水平捲動設定,與 Windows 10 預設樣式中的垂直捲動設定相衝突,因為我們已移植到 Windows 10 應用程式。 第二個問題是該應用程式尚未調整其使用者介面,以在不同大小的視窗和小型裝置上提供最佳體驗。 第三是尚未使用正確的樣式和畫筆,導致大部分文字不可見 (包括可以點擊縮小的群組標題)。 因此,在接下來的三個小節 (SemanticZoom 和 GridView 設計變更調適型 UI通用樣式) 中,我們將解決這三個問題。

SemanticZoom 和 GridView 設計變更

Windows 10 中對 SemanticZoom 控制項的設計變更在 SemanticZoom 變更一節中有所說明。 我們在本節中無需做任何事來應對這些變化。

GridView/ListView 變更一節說明了 GridView 的變更。 我們需要稍微進行一些調整來適應這些變化,如下所述。

  • 在 SeZoUC.xaml 中,在 ZoomedInItemsPanelTemplate,設定 Orientation="Horizontal"GroupPadding="0,0,0,20"
  • 在 SeZoUC.xaml 中,刪除 ZoomedOutItemsPanelTemplate,並從縮小檢視中移除 ItemsPanel 屬性。

就這麼簡單!

調適型 UI

進行此變更後,SeZoUC.xaml 所提供的 UI 版面配置會讓應用程式適合在寬視窗中執行 (這僅適用於大螢幕裝置)。 不過,當應用程式的視窗很窄時 (這種情況通常發生在小型裝置上,但也可能發生在大型裝置上),我們在 Windows Phone Store 應用程式中設計的 UI 就能可以派上用場,其可謂是最恰當的選擇。

我們可以使用調適型「視覺狀態管理器」功能來實現這一點。 我們要設定視覺元素的屬性,以便預設情況下,使用我們在 Windows Phone Store 應用程式中使用的較小範本,以窄型狀態配置 UI。 然後,我們將偵測應用程式的視窗寬度是否大於或等於特定大小 (以有效像素為測量單位),然後我們將根據偵測結果變更視覺元素的屬性,以便取得更大、更寬的版面配置。 我們將這些屬性變更置於視覺狀態中,並將使用調適型觸發程序來連續監控並確定是否套用該視覺狀態,具體取決於視窗的有效像素寬度。 在本例中,我們會對視窗寬度上觸發,但也可以對視窗高度觸發。

此使用案例適用最小視窗寬度 548 epx,因為這是我們想要顯示寬版面配置的最小裝置大小。 手機通常小於 548 epx,因此在這樣的小型裝置上,我們會保留預設的窄型版面配置。 在電腦上,視窗將以預設寬度啟動,其寬度足以觸發切換到寬型狀態。 在這裡,您可以把視窗拖曳成窄型狀態,以顯示兩欄 250x250 大小的項目。 如果比這個大小還窄,系統將停用觸發程序,移除寬視覺狀態,並且預設的窄型版面配置將會生效。

那麼,我們需要設定和變更哪些屬性,來實現這兩種不同的版面配置? 您有兩種選擇,而這兩種選擇的執行方法也不同。

  1. 我們可以在標記中放置兩個 SemanticZoom 控制項。 其中一個控制項是我們在 Windows 執行階段 8.x 應用程式中使用的標記副本 (在其中使用 GridView 控制項),並且預設為摺疊。 另一個控制項是我們在 Windows Phone Store 應用程式中使用的標記副本 (在其中使用 ListView 控制項),並且預設為可見。 視覺狀態將切換兩個 SemanticZoom 控制項的可見度屬性。 這種作法不會太費力,但一般來說,這並不屬於高效能技術。 因此,如果使用這種方式,您最好要分析應用程式,並確保它仍然滿足您的效能目標。
  2. 我們可以使用包含 ListView 控制項的單一 SemanticZoom。 為了實現我們的兩種版面配置,在寬型視覺狀態中,我們要變更 ListView 控制項的屬性,包括套用至其範本,使其配置方式與 GridView 相同。 雖然這種方法效能更佳,但是 GridViewListView 的各種樣式和範本之間,以及它們的各種項目類型之間存在許多細小的差異,因此這種解決方案更難實現。 該解決方案還與目前預設樣式和範本的設計方式緊密結合,為我們提供了一個脆弱且對預設值未來任何變更敏感的解決方案。

在本案例研究中,我們將採用第一種選擇。 但如果您願意,可以嘗試第二個選擇,看看是否更適合您。 以下是實施第一個選擇所需採取的步驟。

  • 在新專案標記中的 SemanticZoom 上,設定 x:Name="wideSeZo"Visibility="Collapsed"
  • 返回 Bookstore2_81.WindowsPhone 專案,並開啟 SeZoUC.xaml。 從該檔案複製 SemanticZoom 元素標記,並將其貼上到新專案中的 wideSeZo 之後。 在您剛剛貼上的元素上設定 x:Name="narrowSeZo"
  • narrowSeZo 需要一些尚未複製的樣式。 同樣地,在 Bookstore2_81.WindowsPhone 中,從 SeZoUC.xaml 複製兩種樣式 (AuthorGroupHeaderContainerStyleZoomedOutAuthorItemContainerStyle),並將其貼到新專案的 BookstoreStyles.xaml 中。
  • 現在,您的新 SeZoUC.xaml 中會有兩個 SemanticZoom 元素。 將這兩個元素包裝在 Grid 中。
  • 在新項目的 BookstoreStyles.xaml 中,將文字 Wide 附加到這三個資源索引鍵 (以及它們在 SeZoUC.xaml 中的參考,但僅限於 wideSeZo 內的參考):AuthorGroupHeaderTemplateZoomedOutAuthorTemplateBookTemplate
  • 在 Bookstore2_81.WindowsPhone 專案中,開啟 BookstoreStyles.xaml。 從此檔案中,複製這三個相同的資源 (如上所述)、兩個捷徑清單項目轉換器,以及命名空間前置詞宣告 Windows_UI_Xaml_Controls_Primitives,然後將它們全部貼到新專案中的 BookstoreStyles.xaml 中。
  • 最後,在新專案的 SeZoUC.xaml 中,將適當的 Visual State Manager 標記新增至上述新增的 Grid 中。
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState x:Name="WideState">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="548"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="wideSeZo.Visibility" Value="Visible"/>
                        <Setter Target="narrowSeZo.Visibility" Value="Collapsed"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

    ...

    </Grid>

通用樣式

現在,讓我們修復一些樣式問題,包括上述從舊專案複製時產生問題。

  • 在 MainPage.xaml 中,將 LayoutRoot 的背景改為 "{ThemeResource ApplicationPageBackgroundThemeBrush}"
  • 在 BookstoreStyles.xaml 中,將資源 TitlePanelMargin 的值設為 0 (或您認為合適的任何值)。
  • 在 SeZoUC.xaml 中,將 wideSeZo 的邊界設定為 0 (或您認為合適的任何值)。
  • 在 BookstoreStyles.xaml 中,從 AuthorGroupHeaderTemplateWide 移除 Margin 屬性。
  • AuthorGroupHeaderTemplateZoomedOutAuthorTemplate 中刪除 FontFamily 屬性。
  • Bookstore2_81 使用 BookTemplateTitleTextBlockStyleBookTemplateAuthorTextBlockStylePageTitleTextBlockStyle 資源索引鍵作為間接取值,以便單一索引鍵在兩個應用程式中具有不同的實作。 我們不再需要這種間接取值;而是可以直接參考系統樣式。 因此,請將整個應用程式中的這些參考分別替換為 TitleTextBlockStyleCaptionTextBlockStyleHeaderTextBlockStyle。 您可以使用 Visual Studio 的在檔案中取代功能來快速且準確地執行此操作。 然後,您可以刪除這三個未使用的資源。
  • AuthorGroupHeaderTemplate 中,將 PhoneAccentBrush 取代為 SystemControlBackgroundAccentBrush,並在 TextBlock 上設定 Foreground="White",以便在行動裝置系列上執行階段看起來正確。
  • BookTemplateWide 中,將 Foreground 屬性從第二個 TextBlock 複製到第一個。
  • ZoomedOutAuthorTemplateWide 中,將對 SubheaderTextBlockStyle 的參考 (現在有點太大) 變更為對 SubtitleTextBlockStyle 的參考。
  • 在新平台中,縮小檢視 (捷徑清單) 不再覆蓋放大檢視,因此我們可以從 narrowSeZo 的縮小檢視中刪除 Background 屬性。
  • 為了使所有樣式和範本都位於一個檔案中,將 ZoomedInItemsPanelTemplate 從 SeZoUC.xaml 移至 BookstoreStyles.xaml 中。

最後一連串的樣式設定會讓應用程式看起來像這樣。

the ported windows 10 app running on a desktop device, zoomed-in view, two sizes of window

在桌面裝置上執行的移植 Windows 10 應用程式,放大檢視,兩種大小的視窗

the ported windows 10 app running on a desktop device, zoomed-out view, two sizes of window

在桌面裝置上執行的移植 Windows 10 應用程式、縮小檢視、兩種大小的視窗

the ported windows 10 app running on a mobile device, zoomed-in view

在行動裝置上執行的移植後 Windows 10 應用程式,放大檢視

the ported windows 10 app running on a mobile device, zoomed-out view

在行動裝置上執行的移植後 Windows 10 應用程式,縮小檢視

推論

此案例研究的使用者介面比前一個案例更複雜。 與先前的案例研究一樣,這個特定的檢視模型根本不需要進行任何作業,我們的工作主要是重構使用者介面。 其中一些變更是將兩個專案合併為一個專案的必然結果,同時仍然支援許多外形規格 (事實上,比我們以前可以支援的要多得多)。 其中一些變更與平台所做的變更有關。

下一個案例研究是 QuizGame,我們將透過此案例了解存取和顯示分組資料。