ユーザー インターフェイスの移行 (WinUI 3 を含む)

このトピックでは、Windows UI ライブラリ (WinUI) 3 への移行など、ユーザー インターフェイス (UI) コードを移行する方法について説明します。

API と機能の違いの概要

Window.Current プロパティは App.Window に移行されます。 そして、CoreDispatcher.RunAsync メソッドは DispatcherQueue.TryEnqueue に移行されます。

ウィンドウの "ハンドル" (HWND) を、MessageDialog およびピッカーに設定する必要があります。

DataTransferManager API を使用するには、それらをウィンドウに関連付ける必要があります。

ContentDialogPopup については、XamlRoot プロパティを設定する必要があります。

Visual State Manager と Page.Resources XAML マークアップのリファクタリングが必要な 場合があります。

Windows App SDK 内では、AcrylicBrush は常にアプリ コンテンツからサンプルを収集します。

Windows.UI.Xaml.Window.Current を App.Window に変更する

このセクションは、UWP アプリで Windows.UI.Xaml.Window.Current プロパティを使用している場合に該当します。 このプロパティは Windows App SDK ではサポートされていないので、このセクションでは、Window.Current を使用する UWP コードを移植する方法について説明します。

// MainPage.xaml.cs in a UWP app
var width = Window.Current.Bounds.Width;
// MainPage.xaml.cpp in a UWP app
auto width{ Window::Current().Bounds().Width };

Windows アプリ SDK アプリでは、App クラスのパブリック静的プロパティを使用して、現在のウィンドウまたはメイン ウィンドウの独自の概念を追加できます。

// App.xaml.cs in a Windows App SDK app
public partial class App : Application
{
    ...
    public static Window Window { get { return m_window; } }
    private static Window m_window;
}
// App.xaml.h in a Windows App SDK app
...
struct App : AppT<App>
{
    ...
    static winrt::Microsoft::UI::Xaml::Window Window(){ return window; };

private:
    static winrt::Microsoft::UI::Xaml::Window window;
};
...

// App.xaml.cpp
...
winrt::Microsoft::UI::Xaml::Window App::window{ nullptr };
...

次に、App クラス自体の内部で、Window.Current を単純に window に変更できます。 App クラスの外部では、次に示すように Window.CurrentApp.Window に変更します。

// MainPage.xaml.cs in a UWP app
var width = App.Window.Bounds.Width;
// MainPage.xaml.cpp in a UWP app
#include <App.xaml.h>
auto width{ App::Window().Bounds().Width };

MessageDialog、およびピッカー

UWP アプリで、Windows.UI.Popups または Windows.Storage.Pickers の名前空間から特定の型を使用する場合、このセクションに含まれている情報は、そのコードの移行に役立ちます。 次のコード例では MessageDialog を使用していますが、ピッカー (FileOpenPickerFileSavePickerFolderPicker など).を表示する場合にまったく同じ手法を適用できます。

デスクトップ アプリで実行する必要がある手順については、「 CoreWindow に依存する WinRT UI オブジェクトを表示する」を参照してください。

注意

新しいアプリの場合は、MessageDialog ではなく ContentDialog コントロールを使用することをお勧めします。 詳細については、以下の「ContentDialog および Popup」セクションを参照してください。

MessageDialog を表示するための一般的な UWP コードを次に示します。

// In a UWP app
var showDialog = new Windows.UI.Popups.MessageDialog("Message here");
await showDialog.ShowAsync();
// In a UWP app
auto showDialog{ Windows::UI::Popups::MessageDialog(L"Message here") };
co_await showDialog.ShowAsync();

また、Windows アプリ SDK アプリの同等のコードを次に示します。

// MainWindow.xaml.cs in a WinUI 3 app
var showDialog = new Windows.UI.Popups.MessageDialog("Message here");
WinRT.Interop.InitializeWithWindow.Initialize(showDialog,
    WinRT.Interop.WindowNative.GetWindowHandle(this));
await showDialog.ShowAsync();
// pch.h in a WinUI 3 app
...
#include <Shobjidl.h>
#include <microsoft.ui.xaml.window.h>
#include <winrt/Windows.UI.Popups.h>
...

// MainWindow.xaml.cpp
...
auto showDialog{ Windows::UI::Popups::MessageDialog(L"Message here") };

auto windowNative{ this->m_inner.as<::IWindowNative>() };
HWND hWnd{ 0 };
windowNative->get_WindowHandle(&hWnd);
showDialog.as<::IInitializeWithWindow>()->Initialize(hWnd);

co_await showDialog.ShowAsync();

DataTransferManager

UWP アプリで、DataTransferManager.ShowShareUI メソッドを呼び出す場合、このセクションに含まれている情報は、そのコードの移行に役立ちます。

ShowShareUI を呼び出す一般的な UWP コードを次に示します。

// In a UWP app
var dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.GetForCurrentView();

dataTransferManager.DataRequested += (sender, args) =>
{
    args.Request.Data.Properties.Title = "In a UWP app...";
    args.Request.Data.SetText("...display the user interface for sharing content with another app.");
    args.Request.Data.RequestedOperation =
        Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
};

Windows.ApplicationModel.DataTransfer.DataTransferManager.ShowShareUI();
// In a UWP app
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
...
auto dataTransferManager{ Windows::ApplicationModel::DataTransfer::DataTransferManager::GetForCurrentView() };

dataTransferManager.DataRequested([](Windows::ApplicationModel::DataTransfer::DataTransferManager const& /* sender */,
    Windows::ApplicationModel::DataTransfer::DataRequestedEventArgs const& args)
    {
        args.Request().Data().Properties().Title(L"In a UWP app...");
        args.Request().Data().SetText(L"...display the user interface for sharing content with another app.");
        args.Request().Data().RequestedOperation(Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy);
    });

Windows::ApplicationModel::DataTransfer::DataTransferManager::ShowShareUI();

Windows App SDK アプリで DataTransferManager.ShowShareUI を使用するには、共有 UI をウィンドウに関連付ける必要があります。 これは手動で行う必要があります。 詳細とコード例については、「 CoreWindow に依存する WinRT UI オブジェクトを表示する」を参照してください。

ContentDialog および Popup

UWP アプリで、Windows.UI.Xaml.Controls.ContentDialog または Windows.UI.Xaml.Controls.Primitives.Popup クラスを使用する場合、このセクションに含まれている情報は、そのコードの移行に役立ちます。 以下のコード例では ContentDialog を使用しますが、まったく同じ手法を利用して Popup オブジェクトを表示できます。

ContentDialog を表示する一般的な UWP コードを次に示します。

// MainPage.xaml.cs in a UWP app
var unsupportedFilesDialog = new ContentDialog();
// Set Title, Content, etc.
await unsupportedFilesDialog.ShowAsync();
// MainPage.xaml.cpp in a UWP app
ContentDialog unsupportedFilesDialog{};
// Set Title, Content, etc.
co_await unsupportedFilesDialog.ShowAsync();

Windows App SDK アプリで、ダイアログの XamlRoot プロパティも設定する必要があります。 以下にその方法を示します。

// MainPage.xaml.cs in a Windows App SDK app
var unsupportedFilesDialog = new ContentDialog();
// Set Title, Content, etc.
unsupportedFilesDialog.XamlRoot = this.Content.XamlRoot;
await unsupportedFilesDialog.ShowAsync();
// MainPage.xaml.cpp in a Windows App SDK app
ContentDialog unsupportedFilesDialog{};
// Set Title, Content, etc.
unsupportedFilesDialog.XamlRoot(this->Content().XamlRoot());
co_await unsupportedFilesDialog.ShowAsync();

ページ ナビゲーションを実装する必要がありますか?

UWP プロジェクトには、アプリに 1 つの Page しか存在しないような単純なアプリであっても、App クラスのメソッド内に既定でナビゲーション コードがあります。

Visual Studio で新しい Windows App SDK プロジェクトを作成すると、プロジェクト テンプレートには MainWindow クラス (Microsoft.UI.Xaml.Window 型) が用意されていますが、Page はありません。 また、プロジェクト テンプレートにはナビゲーション コードが用意されていません。

非常に単純な Windows App SDK アプリ (シングルページ アプリ) については、簡略化できる場合があります。 Windows App SDK プロジェクトにページやユーザー コントロールを作成する必要はないが、代わりに、その単一ページの背後の XAML マークアップとコード ビハインドを MainWindow にコピーする必要がある場合もあります。 ただし、MainWindow でサポートされないものもあります。 Window は DependencyObject でないため、ResourcesDataContext などの機能はそこに存在しません。 LoadUnload などのイベントも存在しません。 詳細と回避策については、「Visual State Manager と Page.Resources」を参照してください。

一方、Windows アプリ SDK アプリ内のページ間のナビゲーションが必要な場合は、UWP アプリから App.OnLaunched メソッドと App::OnNavigationFailed メソッドを移行します。 App.OnLaunched で、ナビゲーション コード (rootFrame を作成し、アプリの最初のページに移動するコード) を見つけ、2 つの既存のコード行 (ウィンドウを作成してアクティブ化する行) の間にマージします。 また、コピーして貼り付けたコードを移行する必要もあります。 簡単なコード例については、「 Page クラス」を参照してください。

Visual State Manager と Page.Resources

ページ ナビゲーションを実装する必要がありますか?」も参照してください。 XAML マークアップとコード ビハインドを MainWindow にコピーできる、十分に単純な UWP アプリがある場合は、これらの例外に気を付けてください。

MainWindow クラス (Microsoft.UI.Xaml.Window 型) はコントロールではないので、Visual State Manager XAML マークアップとコードビハインドはサポートされません (「チュートリアル: アダプティブ レイアウトを作成する」を参照してください)。 しかし、次の 2 つのオプションがあります。

  • UserControl 項目をプロジェクトに追加し、マークアップとコードビハインドをそれに移行します。 次に、そのユーザー コントロールのインスタンスを MainWindow に配置します。
  • Page 項目をプロジェクトに追加し、マークアップとコードビハインドをそれに移行します。 次に、「ページ ナビゲーションを実装する必要がありますか?」の説明に従って、起動時にその Page に移動するように App クラスにコードを追加します。

さらに、<Page.Resources> 要素を MainWindow にコピーして、<Window.Resources> に名前を変更するだけのことができません。 代わりに、MainWindow の XAML マークアップのルート レイアウト コンテナー (Grid など) の下で Resources 要素の親に指定します。 これは次のようになります。

<Window ...>
    <Grid>
        <Grid.Resources>...</Grid.Resources>
        ...
    </Grid>
</Window>

AcrylicBrush.BackgroundSource プロパティ

AcrylicBrush.BackgroundSource プロパティは UWP に存在しますが、Windows App SDK には存在しません。 Windows App SDK 内では、AcrylicBrush は常にアプリ コンテンツからサンプルを収集します。

そのため、UWP アプリのソース コード内で AcrylicBrush.BackgroundSource プロパティにアクセスする場合は (XAML マークアップまたは命令型コードのいずれの場合も)、アプリを Windows App SDK に移行するときにそのコードを削除します。 代わりに、 DesktopAcrylicController クラスを使用します。