Share via


UWP PhotoLab 範例應用程式的 Windows 應用程式 SDK 移轉 (C#)。

本主題是採用 C# UWP PhotoLab 範例應用程式並將其移轉到 Windows 應用程式 SDK 的案例研究。

首先複製 UWP 範例應用的存放庫,然後在 Visual Studio 中開啟解決方案。

重要

如需處理移轉程式的考慮和策略,以及如何設定用於移轉的開發環境,請參閱整體移轉策略。 特別重要的一點是,了解從 UWP 移植到 WinUI 3 時支援的功能,以便在嘗試移轉之前確保應用程式所需的所有功能均受支援。

安裝 Windows 應用程式 SDK 的工具

若要設定您的開發電腦,請參閱安裝 Windows 應用程式 SDK 的工具 (機器翻譯)。

重要

您可以在 Windows 應用程式 SDK 版本通道主題中找到版本資訊主題。 每個通道都有版本資訊。 請務必查看這些版本資訊中的任何限制和已知問題,因為這些可能會影響本案例研究和/或執行移轉的應用程式的結果。

建立新專案

在 Visual Studio 中,從空白應用程式封包 (桌面中的 WinUI 3) 專案範本建立一個新的 C# 專案。 將專案命名為 PhotoLabWinUI,取消選取將解決方案和專案放在同一目錄中。 您可以將目標設為用戶端作業系統的最新版本 (非預覽版)。

注意

我們將引用範例專案的 UWP 版本 (您從其存放庫複製的版本) 作為來源解決方案/專案。 我們將把 Windows 應用程式 SDK 版本稱為目標解決方案/專案。

我們將移轉程式代碼的順序

MainPage 是應用程式的重要且突出的部分。 但如果我們先移轉,那麼我們很快就會意識到 MainPage 依賴 DetailPage 檢視;然後 DetailPage 依賴 ImageFileInfo 模型。 因此,在本逐步解說中,我們將採用此方法。

  • 我們將首先複製資產檔案。
  • 然後,我們將移轉 ImageFileInfo 模型。
  • 接下來,我們將移轉 App 類別 (因為需要對 DetailPageMainPageLoadedImageBrush 所依賴的類別進行更改)。
  • 然後,我們將移轉 LoadedImageBrush 類別。
  • 然後,我們會先從 DetailPage 開始移轉檢視。
  • 我們將藉由移轉 MainPage 檢視來完成。

複製資產檔案

  1. 在 Visual Studio 的目標專案中,在方案總管中,以滑鼠右鍵按一下 Assets 資料夾,然後新增名為 Samples

  2. 在來源專案的複製中,在檔案總管中,找到資料夾 Windows-appsample-photo-lab>PhotoLab>Assets。 您會在該資料夾中找到七個資產檔案,以及名為 Samples 的子資料夾,其中包含範例影像。 選取這七個資產檔案和範例子資料夾,並將其複製到剪貼簿。

  3. 此外,在檔案總管中,現在會在您所建立的目標專案中找到對應的資料夾。 該資料夾的路徑是 PhotoLabWinUI>PhotoLabWinUI>Assets。 將剛剛複製的資產文件和子資料夾貼上到該資料夾中,並接受提示以替換目標中已存在的任何文件。

  4. 在 Visual Studio 中的目標專案中,在方案總管中,隨著 Assets 資料夾展開,您將在 Samples 資料夾中看到 Samples 子資料夾 (您剛剛貼上的) 的內容。 您可以將滑鼠指標懸停在資源檔案上。 每個資源檔案都會顯示縮圖預覽,確認您已正確取代/新增資源檔案。

移轉 ImageFileInfo 模型

ImageFileInfo 是表示圖像檔案 (例如照片) 的模型 (在模型、視圖和視圖模型的意義上)。

複製 ImageFileInfo 原始程式碼檔案

  1. 在來源專案的複製中,在檔案總管中,找到資料夾 Windows-appsample-photo-lab>PhotoLab。 在該資料夾中,您會找到原始程式碼檔案ImageFileInfo.cs;該檔案包含 ImageFileInfo 的實作。 選取該檔案,並將它複製到剪貼簿。

  2. 在 Visual Studio 中,右鍵按兩下目標項目節點,然後按兩下在檔案總管中打開資料夾。 這會在檔案總管中開啟目標專案資料夾。 將您剛複製的檔案貼到該資料夾中。

移轉 ImageFileInfo 原始程式碼

  1. 將尋找/取代專案 (比對大小寫和整字) 放在您剛貼上的 ImageFileInfo.cs 檔案中。
  • namespace PhotoLab =>namespace PhotoLabWinUI
  • Windows.UI.Xaml =>Microsoft.UI.Xaml

Windows.UI.Xaml 是 UWP XAML 的命名空間;Microsoft.UI.Xaml 是 WinUI XAML 的命名空間。

注意

UWP API 對應到 Windows 應用程式 SDK 主題提供了 UWP API 到其 Windows 應用程式 SDK 等效項的對應。 我們上面所做的更改是移轉過程中所需的命名空間名稱更改的範例。

  1. 現在確認您可以建置目標解決方案 (但尚未執行)。

移轉 App 類別

  1. 從來源專案中的<Application.Resources>元素中App.xaml,尋找下列四行。 複製它們,並將其貼到目標專案中。
<SolidColorBrush x:Key="RatingControlSelectedForeground" Color="White"/>
<!--  Window width adaptive breakpoints.  -->
<x:Double x:Key="MinWindowBreakpoint">0</x:Double>
<x:Double x:Key="MediumWindowBreakpoint">641</x:Double>
<x:Double x:Key="LargeWindowBreakpoint">1008</x:Double>

注意

由於目標項目將使用與來源項目不同 (且更簡單) 的導航,因此無需從來源項目的 App.xaml.cs

  1. 在目標專案中,App 會將主視窗物件儲存在其私人欄位 m_window。 稍後在移轉過程中 (當我們移轉來源項目對 Window.Current 的使用時),如果將該私有欄位改為公共靜態屬性,將會很方便。 因此,將 m_window 欄位替換為 Window 屬性,並變更對 m_window 的引用,如下所示。
// App.xaml.cs
public partial class App : Application
{
    ...
    protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        Window = new MainWindow();
        Window.Activate();
    }

    public static MainWindow Window { get; private set; }
}
  1. 稍後在移轉過程中 (當我們移轉顯示 FileSavePicker 的程式碼時),如果 App 公開主視窗的處理常式 (HWND),將會很方便。 因此,新增 WindowHandle 屬性,並在 OnLaunched 方法中初始化它,如下所示。
// App.xaml.cs
public partial class App : Application
{
    ...
    protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
    {
        Window = new MainWindow();
        Window.Activate();
        WindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(Window);
    }

    public static IntPtr WindowHandle { get; private set; }
}

移轉 LoadedImageBrush 模型

LoadedImageBrush 是 XamlCompositionBrushBase 的特殊化PhotoLab 範例應用程式會使用 LoadedImageBrush 類別將效果套用至相片。

參考 Win2D NuGet 套件

若要支援 LoadedImageBrush 中的程式代碼,來源專案相依於 Win2D。 因此,我們也需要在目標專案中相依於 Win2D。

在 Visual Studio 的目標解決方案中,按兩下工具> NuGet 封裝管理員>管理解決方案的 NuGet 套件...。>瀏覽並輸入或貼上 Microsoft.Graphics.Win2D。 在搜尋結果中選擇正確的項,選中 PhotoLabWinUI 專案,然後按兩下安裝將封包安裝到該專案中。

複製 LoadedImageBrush 原始程式碼檔案

以您複製 LoadedImageBrush.cs 的相同方式,從來源專案複製到ImageFileInfo.cs目標專案。

移轉 LoadedImageBrush 原始程式碼

  1. 將尋找/取代專案 (比對大小寫和整字) 放在您剛貼上的 LoadedImageBrush.cs 檔案中。
  1. 確認您可以建置目標解決方案 (但尚未執行)。

移轉 DetailPage 檢視

DetailPage 是代表相片編輯器頁面的類別,其中 Win2D 效果會切換、設定及連結在一起。 選取 MainPage 上的相片縮圖,即可進入相片編輯器頁面。 DetailPage 是一種 模型 (在模型、檢視和 ViewModel 的意義上)。

複製 DetailPage 原始碼檔案

以您在先前步驟中複製檔案的方式,將 DetailPage.xamlDetailPage.xaml.cs 從來源專案複製到目標專案。

移轉 DetailPage 原始程式碼

  1. 將尋找/取代專案 (比對大小寫和整字) 放在您剛貼上的 DetailPage.xaml 檔案中。
  • PhotoLab =>PhotoLabWinUI
  1. 將尋找/取代專案 (比對大小寫和整字) 放在您剛貼上的 DetailPage.xaml.cs 檔案中。
  • namespace PhotoLab =>namespace PhotoLabWinUI
  • Windows.UI.Colors =>Microsoft.UI.Colors
  • Windows.UI.Xaml =>Microsoft.UI.Xaml
  1. 在下一個步驟中,我們將進行 ContentDialog 和 Popup 中說明的變更。 因此,仍然在 DetailPage.xaml.cs 中的 ShowSaveDialog 方法中,在該行之前新增此程式碼ContentDialogResult result = await saveDialog.ShowAsync();
if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
    saveDialog.XamlRoot = this.Content.XamlRoot;
}
  1. 還是在 DetailPage.xaml.csOnNavigateTo 方法中,刪除下面兩行程式碼。 就這兩行;在本案例研究的後面,我們將重新引入剛剛刪除的後退按鈕功能。
...
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
    AppViewBackButtonVisibility.Visible;
...
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = 
    AppViewBackButtonVisibility.Collapsed;
...
  1. 對於此步驟,我們將進行 MessageDialog 和 Pickers 中說明的變更。 還是在 DetailPage.xaml.csExportImage 方法中,在該行之前加入這行程式碼var outputFile = await fileSavePicker.PickSaveFileAsync();
WinRT.Interop.InitializeWithWindow.Initialize(fileSavePicker, App.WindowHandle);

MainPage 有 DetailPage 的相依性,這就是為什麼我們先移轉 DetailPage 的原因。 但 DetailPage 也依賴 MainPage,因此我們還無法建置。

移轉 MainPage 檢視

應用程式的主頁代表您執行應用程式時首先看到的檢視。 該頁面從範例應用程式內建的範例資料夾中載入照片,並顯示平鋪縮圖檢視。

複製 MainPage 原始碼檔案

以您在先前步驟中複製檔案的方式,將 MainPage.xamlMainPage.xaml.cs 從來源專案複製到目標專案。

移轉 MainPage 原始程式碼

  1. 將尋找/取代專案 (比對大小寫和整字) 放在您剛貼上的 MainPage.xaml 檔案中。
  • PhotoLab =>PhotoLabWinUI
  1. 仍在 MainPage.xaml 中,尋找標記 animations:ReorderGridAnimation.Duration="400",並刪除該標記。

  2. 將尋找/取代專案 (比對大小寫和整字) 放在您剛貼上的 MainPage.xaml.cs 檔案中。

  • namespace PhotoLab =>namespace PhotoLabWinUI
  • Windows.UI.Xaml =>Microsoft.UI.Xaml
  1. 在此步驟中,我們將進行 ContentDialog 和 Popup 中說明的變更。 因此,仍然在 MainPage.xaml.csGetItemsAsync 方法中的行之前新增此程式碼ContentDialogResult resultNotUsed = await unsupportedFilesDialog.ShowAsync();
if (Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
    unsupportedFilesDialog.XamlRoot = this.Content.XamlRoot;
}
  1. 還是在 MainPage.xaml.csOnNavigateTo 方法中,刪除下面行程式碼。
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
    AppViewBackButtonVisibility.Collapsed;

稍後在本案例研究中,我們將重新引進我們剛才移除的返回按鈕功能。

  1. 確認您可以建置目標解決方案 (但尚未執行)。

PhotoLab 範例應用程式使用導航邏輯最初導覽至 MainPage (然後在 MainPageDetailPage 之間)。 如需 Windows 應用程式 SDK 需要瀏覽的應用程式的詳細資訊 (以及不需要瀏覽的應用程式),請參閱是否需要實作頁面導覽?

因此,我們將進行下一個導覽的支持變更。

  1. MainWindow.xaml 中,刪除 <StackPanel> 專案,並將它取代為只有具名 <Frame> 元素。 結果如下所示:
<Window ...>
    <Frame x:Name="rootFrame"/>
</Window>
  1. 開啟 MainWindow.xaml.cs,然後刪除 myButton_Click 方法。

  2. 仍然在 MainWindow.xaml.cs 中,將以下程式碼行新增至建構函式中。

public sealed partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
        rootFrame.Navigate(typeof(MainPage));
    }
}
  1. 確認您可以建置目標解決方案 (但尚未執行)。

還原返回按鈕功能

  1. DetailPage.xaml 中,根元素是 RelativePanel。 在該 RelativePanel 內緊鄰StackPanel 元素之後加入以下標記。
<AppBarButton x:Name="BackButton" Click="BackButton_Click" Margin="0,0,12,0">
    <SymbolIcon Symbol="Back"/>
</AppBarButton>
  1. DetailPage.xaml.cs 中,將下列兩行程序代碼新增至 OnNavigatedTo 方法,在指示的位置。
if (this.Frame.CanGoBack)
{
    BackButton.Visibility = Microsoft.UI.Xaml.Visibility.Visible;
}
else
{
    BackButton.Visibility = Microsoft.UI.Xaml.Visibility.Collapsed;
}
  1. 仍然在 DetailPage.xaml.cs 新增以下事件處理程式。
private void BackButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
    Frame.GoBack();
}

測試已移轉的應用程式

現在生成專案,並執行應用進行測試。 選取影像、設定縮放層級、選擇效果,並加以設定。