Windows Phone Silverlight 至 UWP 案例研究:Bookstore1Windows Phone Silverlight to UWP case study: Bookstore1

本主題提供將一個非常簡單的 Windows Phone Silverlight App 移植到 Windows 10 通用 Windows 平台 (UWP) App 的案例研究。This topic presents a case study of porting a very simple Windows Phone Silverlight app to a Windows 10 Universal Windows Platform (UWP) app. 您可以使用 Windows 10,來建立可供客戶安裝至各種類型裝置的單一 app 套件,而那就是我們將在這個案例研究中執行的工作。With Windows 10, you can create a single app package that your customers can install onto a wide range of devices, and that's what we'll do in this case study. 請參閱 UWP app 指南See Guide to UWP apps.

我們將移植的 app 包含繫結到檢視模型的 ListBoxThe app we'll port consists of a ListBox bound to a view model. 此檢視模型有一個顯示書名、作者及封面的書籍清單。The view model has a list of books that shows title, author, and book cover. 書籍封面影像的 組建動作 設定為 [ 內容 ],並將 [ 複製到輸出目錄 ] 設為 [ 不要複製]。The book cover images have Build Action set to Content and Copy to Output Directory set to Do not copy.

本節之前的主題說明平台之間的差異,並針對 app 各個方面 (從 XAML 標記、經過繫結到檢視模型,再到存取資料) 的移植程序,提供深入的詳細資料和指導方針。The previous topics in this section describe the differences between the platforms, and they give details and guidance on the porting process for various aspects of an app from XAML markup, through binding to a view model, down to accessing data. 案例研究旨在藉由真實範例中的運作示範,來為該指導方針提供補充。A case study aims to complement that guidance by showing it in action in a real example. 這些案例研究是假設您已看過指導方針,因此不會重複其內容。The case studies assume you've read the guidance, which they do not repeat.

注意   _在 Visual Studio 中開啟 Bookstore1Universal 10 時,如果您看到「需要更新 Visual Studio」訊息,請遵循在TargetPlatformVersion中選取目標平臺版本設定的步驟。Note   When opening Bookstore1Universal_10 in Visual Studio, if you see the message "Visual Studio update required", then follow the steps for selecting a Target Platform Versioning in TargetPlatformVersion.

下載Downloads

下載 Bookstore1WPSL8 Windows Phone Silverlight appDownload the Bookstore1WPSL8 Windows Phone Silverlight app.

下載 Bookstore1Universal _ 10 Windows 10 應用程式Download the Bookstore1Universal_10 Windows 10 app.

Windows Phone Silverlight appThe Windows Phone Silverlight app

以下是我們即將移植的 Bookstore1WPSL8 app 的外觀。Here’s what Bookstore1WPSL8—the app that we're going to port—looks like. 它是一個垂直捲動的書籍清單方塊,位於 app 名稱的標題和網頁標題下方:It's just a vertically-scrolling list box of books beneath the heading of the app's name and page title.

bookstore1wpsl8 的外觀

移植到 Windows 10 專案Porting to a Windows 10 project

這是一項非常快速的工作,可在 Visual Studio 中建立新專案、從 Bookstore1WPSL8 將檔案複製到其中,以及在新專案中包含複製的檔案。It's a very quick task to create a new project in Visual Studio, copy files over to it from Bookstore1WPSL8, and include the copied files in the new project. 一開始先建立新的空白應用程式 (Windows 通用) 專案。Start by creating a new Blank Application (Windows Universal) project. 將它命名為 Bookstore1Universal _ 10。Name it Bookstore1Universal_10. 這些是要從 Bookstore1WPSL8 複製到 Bookstore1Universal 10 的檔案 _ 。These are the files to copy over from Bookstore1WPSL8 to Bookstore1Universal_10.

  • 複製包含書籍封面影像 PNG 檔案的資料夾 (該資料夾是 \ \ CoverImages) 的資產。Copy the folder containing the book cover image PNG files (the folder is \Assets\CoverImages). 在複製資料夾之後,請在 [方案總管] 中,確定 [顯示所有檔案] 已切換成開啟。After copying the folder, in Solution Explorer, make sure Show All Files is toggled on. 以滑鼠右鍵按一下您複製的資料夾,然後按一下 [ 包含在專案中]。Right-click the folder that you copied and click Include In Project. 該命令就是我們所謂的在專案中「包含」檔案或資料夾。That command is what we mean by "including" files or folders in a project. 每次複製檔案或資料夾時,請按一下方案總管中的 [重新整理],然後在專案中包含檔案或資料夾。Each time you copy a file or folder, click Refresh in Solution Explorer and then include the file or folder in the project. 不需要對目的地中您正在取代的檔案執行此動作。There's no need to do this for files that you're replacing in the destination.
  • 複製包含視圖模型來源檔案的資料夾 (資料夾 \ ViewModel) 。Copy the folder containing the view model source file (the folder is \ViewModel).
  • 複製 MainPage.xaml 並取代目的地中的檔案。Copy MainPage.xaml and replace the file in the destination.

我們可以保留 App.xaml,以及 Visual Studio 在 Windows 10 專案中為我們產生的 App.xaml.cs。We can keep the App.xaml, and App.xaml.cs that Visual Studio generated for us in the Windows 10 project.

編輯您剛剛複製的原始程式碼和標記檔案,並將 Bookstore1WPSL8 命名空間的任何參考變更為 Bookstore1Universal _ 10。Edit the source code and markup files that you just copied and change any references to the Bookstore1WPSL8 namespace to Bookstore1Universal_10. 快速的方法是使用 [檔案 中取代 ] 功能。A quick way to do that is to use the Replace In Files feature. 在檢視模型原始程式檔的命令式程式碼中,需要進行下列移植變更:In the imperative code in the view model source file, these porting changes are needed:

  • 變更 System.ComponentModel.DesignerPropertiesDesignMode ,然後在其上使用 [ 解析 ] 命令。Change System.ComponentModel.DesignerProperties to DesignMode and then use the Resolve command on it. 刪除 IsInDesignTool 屬性,然後使用 IntelliSense 來新增正確的屬性名稱:DesignModeEnabledDelete the IsInDesignTool property and use IntelliSense to add the correct property name: DesignModeEnabled.
  • 使用的 [ 解析 ] 命令 ImageSourceUse the Resolve command on ImageSource.
  • 使用的 [ 解析 ] 命令 BitmapImageUse the Resolve command on BitmapImage.
  • 刪除 using System.Windows.Media;using System.Windows.Media.Imaging;Delete using System.Windows.Media; and using System.Windows.Media.Imaging;.
  • Bookstore1Universal _ 10. BookstoreViewModel 的傳回值從 "BOOKSTORE1WPSL8" 變更為 "Bookstore1Universal"。Change the value returned by the Bookstore1Universal_10.BookstoreViewModel.AppName property from "BOOKSTORE1WPSL8" to "BOOKSTORE1UNIVERSAL".

在 MainPage.xaml 中,需要進行下列移植變更:In MainPage.xaml, these porting changes are needed:

  • phone:PhoneApplicationPage 變更為 Page (別忘了變更出現在屬性元素語法中的部分)。Change phone:PhoneApplicationPage to Page (don't forget the occurrences in property element syntax).
  • 刪除 phoneshell 命名空間前置字元宣告。Delete the phone and shell namespace prefix declarations.
  • 將其餘命名空間前置字元宣告中的 "clr-namespace" 變更為 "using"。Change "clr-namespace" to "using" in the remaining namespace prefix declaration.

如果我們想要以最快的方式看到結果,我們可以選擇非常不費力的方式來更正標記編譯錯誤,即使這意謂著暫時移除標記。We can choose to correct markup compilation errors very cheaply if we want to see results soonest, even if that means temporarily removing markup. 但是讓我們記下因為這麼做所導致的負債。But, let's keep a record of the debt we accrue by doing so. 以下是此案例的做法:Here it is in this case.

  1. MainPage.xaml 的根 Page 元素中,刪除 SupportedOrientations="Portrait"In the root Page element in MainPage.xaml, delete SupportedOrientations="Portrait".
  2. MainPage.xaml 的根 Page 元素中,刪除 Orientation="Portrait"In the root Page element in MainPage.xaml, delete Orientation="Portrait".
  3. MainPage.xaml 的根 Page 元素中,刪除 shell:SystemTray.IsVisible="True"In the root Page element in MainPage.xaml, delete shell:SystemTray.IsVisible="True".
  4. BookTemplate 資料範本中,刪除了對 PhoneTextExtraLargeStylePhoneTextSubtleStyleTextBlock 樣式的參考。In the BookTemplate data template, delete the references to the PhoneTextExtraLargeStyle and PhoneTextSubtleStyleTextBlock styles.
  5. TitlePanelStackPanel 中,刪除了對 PhoneTextNormalStylePhoneTextTitle1StyleTextBlock 樣式的參考。In the TitlePanelStackPanel, delete the references to the PhoneTextNormalStyle and PhoneTextTitle1StyleTextBlock styles.

首先讓我們處理行動裝置系列的 UI,我們可以在之後考量其他尺寸。Let's work on the UI for the mobile device family first, and we can consider other form factors after that. 您現在可以建置與執行 app。You can build and run the app now. 以下是它在行動裝置模擬器上的外觀。Here's how it looks on the mobile emulator.

行動裝置上包含初始原始程式碼變更的 UWP app

檢視與檢視模型一起正常運作,而 ListBox 也功能正常。The view and the view model are working together correctly, and the ListBox is functioning. 我們通常只需要修正樣式並讓影像顯示即可。We mostly just need to fix the styling and get the images to show up.

清償負債項目,以及一些初始樣式Paying off the debt items, and some initial styling

預設支援所有方向。By default, all orientations are supported. 不過,Windows Phone Silverlight 應用程式明確地將本身限制為僅限直向,因此債務專案 # 1 和 # 2 會藉由進入新專案中的應用程式套件資訊清單,並在支援的方向進行縱向檢查來支付費用。The Windows Phone Silverlight app explicitly constrains itself to portrait-only, though, so debt items #1 and #2 are paid off by going into the app package manifest in the new project and checking Portrait under Supported orientations.

針對此應用程式, # 因為預設會顯示狀態列 (先前稱為系統匣) ,所以專案3不是債務。For this app, item #3 is not a debt since the status bar (formerly called the system tray) is shown by default. 針對專案 # 4 和 # 5,我們需要找出四個通用 WINDOWS 平臺 (UWP)  TextBlock 樣式,以對應至我們所使用的 Windows Phone Silverlight 樣式。For items #4 and #5, we need to find four Universal Windows Platform (UWP) TextBlock styles that correspond to the Windows Phone Silverlight styles that we were using. 我可以在模擬器中執行 Windows Phone Silverlight app,並將它與文字區段中的圖例互相比較。You can run the Windows Phone Silverlight app in the emulator and compare it side-by-side with the illustration in the Text section. 那樣做並查看 Windows Phone Silverlight 系統樣式的屬性之後,我們便可製作出下表:From doing that, and from looking at the properties of the Windows Phone Silverlight system styles, we can make this table.

| Windows Phone Silverlight 樣式索引鍵Windows Phone Silverlight style key | UWP 樣式索引鍵UWP style key | |-------------------------------------|------------------------| | PhoneTextExtraLargeStylePhoneTextExtraLargeStyle | TitleTextBlockStyleTitleTextBlockStyle | | PhoneTextSubtleStylePhoneTextSubtleStyle | SubtitleTextBlockStyleSubtitleTextBlockStyle | | PhoneTextNormalStylePhoneTextNormalStyle | CaptionTextBlockStyleCaptionTextBlockStyle | | PhoneTextTitle1StylePhoneTextTitle1Style | HeaderTextBlockStyleHeaderTextBlockStyle |   若要設定這些樣式,您可以直接在標記編輯器中輸入它們,或是使用 Visual Studio XAML 工具並設定它們,而不需要輸入任何內容。To set those styles, you can just type them into the markup editor or you can use the Visual Studio XAML Tools and set them without typing a thing. 若要這樣做,請以滑鼠右鍵按一下 TextBlock ,然後按一下 [ 編輯樣式套用 > 資源]。To do that, you right-click a TextBlock and click Edit Style > Apply Resource. 若要使用專案範本中的 TextBlock來這麼做,請以滑鼠右鍵按一下 ListBox ,然後按一下 [ 編輯其他範本], > **編輯產生的專案 (ItemTemplate) **。To do that with the TextBlocks in the item template, right click the ListBox and click Edit Additional Templates > Edit Generated Items (ItemTemplate).

項目後方有 80% 不透明的白色背景,因為 ListBox 控制項的預設樣式將其背景設定為 ListBoxBackgroundThemeBrush 系統資源。There is an 80% opaque white background behind the items, because the default style of the ListBox control sets its background to the ListBoxBackgroundThemeBrush system resource. ListBox 上設定 Background="Transparent" 以清除該背景。Set Background="Transparent" on the ListBox to clear that background. 若要將項目範本中的 TextBlock 靠左對齊,請以上述方式再次編輯它,然後將兩個 TextBlock 上的 Margin 都設定為 "9.6,0"To left-align the TextBlocks in the item template, edit it again the same way as described above and set a Margin of "9.6,0" on both TextBlocks.

完成後,因為變更與檢視像素相關,所以我們需要將我們尚未變更的所有固定大小維度 (邊界、寬度、高度等等) 逐一乘以 0.8 。After that is done, because of changes related to view pixels, we need to go through and multiply any fixed size dimension that we haven’t yet changed (margins, width, height, etc) by 0.8. 例如,影像應該從 70x70px 變更為 56x56px。So, for example, the images should change from 70x70px to 56x56px.

但是讓我們在顯示樣式結果之前,先取得這些影像。But, let’s get those images to render before we show the results of our styling.

將影像繫結到檢視模型Binding an Image to a view model

在 Bookstore1WPSL8 中,我們是這麼做:In Bookstore1WPSL8, we did this:

    // this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
    return new BitmapImage(new Uri(this.CoverImagePath, UriKind.Relative));

在 Bookstore1Universal,我們將使用 ms-appx URI 配置In Bookstore1Universal, we use the ms-appx URI scheme. 如此,我們便可以讓程式碼的其餘部分保持不變,我們可以使用不同的 System.Uri 建構函式多載將 ms-appx URI 配置放在基底 URI 中,然後將路徑的其餘部分附加至其上。So that we can keep the rest of our code the same, we can use a different overload of the System.Uri constructor to put the ms-appx URI scheme in a base URI and append the rest of the path onto that. 例如:Like this:

    // this.BookCoverImagePath contains a path of the form "/Assets/CoverImages/one.png".
    return new BitmapImage(new Uri(new Uri("ms-appx://"), this.CoverImagePath));

通用樣式Universal styling

現在我們只需要進行一些最終樣式調整,並確認應用程式的外觀在桌面 (和其他) 尺寸和行動裝置尺寸上一樣適當。Now, we just need to make some final styling tweaks and confirm that the app looks good on desktop (and other) form factors as well as mobile. 步驟如下。The steps are below. 而且您可以使用此主題頂端的連結來下載專案,並查看這裡和案例研究結束時所有變更的結果。And you can use the links at the top of this topic to download the projects and see the results of all the changes between here and the end of the case study.

  • 若要盡可能縮短項目之間的間距,請找出 MainPage.xaml 中的 BookTemplate 資料範本,並將 Margin 屬性從根目錄 Grid 中刪除。To tighten up the spacing between items, find the BookTemplate data template in MainPage.xaml and delete the Margin attribute from the root Grid.
  • 如果您想要讓頁面標題有更多的空間,您可以將頁面標題 TextBlock-5.6 的下邊界重設為 0If you want to give the page title a little more breathing room, you can reset the bottom margin of -5.6 to 0 on the page title TextBlock.
  • 現在我們需要將 LayoutRoot 的背景設為正確的預設值,如此一來,無論使用哪一種佈景主題,app 在所有裝置上執行時都會具有適當的外觀。Now, we need to set LayoutRoot's Background to the correct default value so that the app looks appropriate when running on all devices no matter what the theme is. 請將它從 "Transparent" 變更為 "{ThemeResource ApplicationPageBackgroundThemeBrush}"Change it from "Transparent" to "{ThemeResource ApplicationPageBackgroundThemeBrush}".

若是更複雜的 app,這會是我們使用尺寸和使用者經驗的移植中指導方針的時機,且在可以執行 app 的許多裝置上,真正選擇性地使用尺寸。With a more sophisticated app, this would be the point at which we'd use the guidance in Porting for form factor and user experience and really make optimal use of the form factor of each of the many devices the app can now run on. 但是針對這個簡單的應用程式,我們可以稍微在這裡停下,並查看應用程式在最後一個樣式設定操作順序後的外觀。But, for this simple app, we can stop here and see how the app looks after that last sequence of styling operations. 它實際在行動裝置與桌面裝置上看起來相同,雖然它並未妥善使用寬尺寸的空間 (但我們將在稍後的案例研究中深入討論)。It actually looks the same on mobile and desktop devices, although it's not making best use of space on wide form factors (but we'll investigate how to do that in a later case study).

請參閱佈景主題變更,了解如何控制您 app 的佈景主題。See Theme changes to see how to control the theme of your app.

移植完成的 Windows 10 app

移植完成且正在行動裝置上執行的 Windows 10 appThe ported Windows 10 app running on a Mobile device

選擇性調整行動裝置的清單方塊An optional adjustment to the list box for Mobile devices

當應用程式在行動裝置上執行時,兩個佈景主題中清單方塊的背景顏色都是預設為淺色。When the app is running on a Mobile device, the background of a list box is light by default in both themes. 這可能會是您喜歡的樣式,如果是這樣的話,就不需要再執行其他動作。That may be the style that you prefer and, if so, then there's nothing more to do. 但是控制項的設計可讓您自訂它們的外觀,卻不會影響它們的行為。But, controls are designed so that you can customize their look while leaving their behavior unaffected. 因此,如果您希望清單方塊套用深色佈景主題 (原始 app 外觀),請依照<選擇性調整>下方的這些指示執行。So, if you want the list box to be dark in the dark theme—the way the original app looked—then follow these instructions under "An optional adjustment".

結論Conclusion

這個案例研究示範移植一個非常簡單之 app 的程序—可以說是相當不實際的簡單 app。This case study showed the process of porting a very simple app—arguably an unrealistically simple one. 例如,清單控制項可用來進行選取或用來建立要瀏覽的內容;app 會瀏覽到含有所點選之項目的更多相關詳細資料的頁面。For instance, list controls can be used for selection or for establishing a context for navigation; the app navigates to a page with more details about the item that was tapped. 這個特定的應用程式既不處理使用者的選項,也沒有任何瀏覽。This particular app does nothing with the user's selection, and it has no navigation. 即使如此,提供此案例研究是為了介紹移植程序,並示範您能用於實際 UWP app 的重要程式碼共用技術。Even so, the case study served to break the ice, to introduce the porting process, and to demonstrate important techniques that you can use in real UWP apps.

下一個案例研究是 Bookstore2,我們將在其中探討如何存取和顯示分組資料。The next case study is Bookstore2, in which we look at accessing and displaying grouped data.