アプリの複数のビューの表示

複数のウィンドウでアプリを表示するワイヤーフレーム

アプリの独立した部分を別々のウィンドウで表示できるようにすることは、ユーザーが生産性を高めるために役立ちます。 アプリに複数のウィンドウを作成すると、タスクバーに各ウィンドウが別々に表示されます。 ユーザーはアプリ ウィンドウの移動、サイズ変更、表示、非表示を個別に行うことができます。また、個別のアプリの場合と同じように各アプリ ウィンドウを切り替えることができます。

重要な API:Windows.UI.ViewManagement namespaceWindows.UI.WindowManagement namespace

アプリが複数のビューを使用する場合

複数のビューによるメリットを活用できる、さまざまなシナリオがあります。 以下は例です。

  • 受信したメッセージの一覧を表示しながら、新しいメールを作成できるメール アプリ
  • 複数の連絡先情報を並列に表示して比較できるアドレス帳アプリ
  • 再生中の曲の情報を表示しながら、その他の利用可能な曲のリストを閲覧できるミュージック プレイヤー アプリ
  • ノートの 1 つのページから別のページに情報をコピーできるメモ アプリ
  • すべてのヘッドライン概要に目を通しながら、後から読むための記事を複数開くことができる閲覧アプリ

各アプリのレイアウトはそれぞれ異なりますが、「新しいウィンドウ」ボタンを予測可能な場所に含めることを推奨します。たとえば、新しいウィンドウで開くことができるコンテンツの右上隅などです。 さらに、[新しいウィンドウで開く] ためのコンテキスト メニュー オプションを含めることを検討します。

アプリの別のインスタンス (同じインスタンスの別のウィンドウではなく) を作成するには、マルチインスタンスの Windows アプリの作成に関するページをご覧ください。

ウィンドウ化ホスト

アプリ内で Windows コンテンツをホストできるさまざまな方法があります。

  • CoreWindow/ApplicationView

    アプリのビューは、スレッドとウィンドウが 1:1 で対応したもので、アプリがコンテンツの表示に使います。 アプリの起動時に最初に作成されるビューは、メイン ビューと呼ばれます。 各 CoreWindow/ApplicationView は、独自のスレッドで動作します。 さまざまな UI スレッドを操作する必要がある場合、マルチウィンドウ アプリが複雑になる可能性があります。

    アプリのメイン ビューは、常に ApplicationView でホストされます。 セカンダリ ウィンドウ内のコンテンツは、ApplicationView または AppWindow でホストできます。

    ApplicationView を使用して、アプリでセカンダリ ウィンドウを表示する方法については、「ApplicationView の使用」を参照してください。

  • AppWindow

    AppWindow は作成元と同じ UI スレッド上で動作するので、これを使用することでマルチウィンドウ Windows アプリの作成が簡単になります。

    WindowManagement 名前空間内の AppWindow クラスやその他の API は、Windows 10 バージョン 1903 (SDK 18362) 以降で使用できます。 アプリで以前のバージョンの Windows 10 を対象としている場合は、ApplicationView を使用して、セカンダリ ウィンドウを作成する必要があります。

    AppWindow を使用して、アプリでセカンダリ ウィンドウを表示する方法については、「AppWindow の使用」を参照してください。

    注意

    AppWindow は現在、プレビュー段階です。 つまり、AppWindow を使用するアプリを Store に送信することはできますが、一部のプラットフォームおよびフレームワーク コンポーネントが AppWindow では動作しないことがわかっています (「制限事項」を参照)。

  • DesktopWindowXamlSource (XAML Islands)

    Win32 アプリ内の UWP XAML コンテンツ (HWND を使用) は、XAML Islands とも呼ばれ、DesktopWindowXamlSource でホストされます。

    XAML Islands の詳細については、デスクトップ アプリケーションでの UWP XAML ホスティング API の使用に関するページを参照してください

ウィンドウ化ホスト間でコードを移植可能にする

XAML コンテンツが CoreWindow に表示される場合、常に ApplicationView および XAML Window が関連付けられています。 これらのクラスで API を使用すると、ウィンドウの境界などの情報を取得できます。 これらのクラスのインスタンスを取得するには、静的 CoreWindow.GetForCurrentThread メソッド、ApplicationView.GetForCurrentView メソッド、または Window.Current プロパティを使用します。 また、GetForCurrentView パターンを使用して、DisplayInformation.GetForCurrentView などのクラスのインスタンスを取得するクラスも多数あります。

これらの API は、CoreWindow/ApplicationView の XAML コンテンツのツリーが 1 つしかなく、XAML には、それがホストされているコンテキストがその CoreWindow/ApplicationView であることがわかっているため、機能します。

XAML コンテンツが AppWindow または DesktopWindowXamlSource 内で実行している場合、複数の XAML コンテンツのツリーを同じスレッドで同時に実行させることができます。 この場合、コンテンツが現在の CoreWindow/ApplicationView (および XAML ウィンドウ) 内で実行されなくなるため、これらの API から適切な情報が得られません。

すべてのウィンドウ化ホストでコードが正常に動作するようにするには、CoreWindowApplicationView、および WindowXamlRoot クラスからコンテキストを取得する新しい API に置き換える必要があります。 XamlRoot クラスは、XAML コンテンツのツリー、およびそれがホストされているコンテキストに関する情報を表します。それが CoreWindow、AppWindow、DesktopWindowXamlSource のいずれでも同じです。 この抽象化レイヤーを使用すると、XAML が実行されるウィンドウ化ホストに関係なく、同じコードを記述できます。

この表では、ウィンドウ化ホスト間で正常に機能しないコードと、それと置換できる新しい移植可能コード、および変更する必要のない API を示しています。

使用していた場合... 置換先...
CoreWindow.GetForCurrentThread().Bounds uiElement.XamlRoot.Size
CoreWindow.GetForCurrentThread().SizeChanged uiElement.XamlRoot.Changed
CoreWindow.Visible uiElement.XamlRoot.IsHostVisible
CoreWindow.VisibilityChanged uiElement.XamlRoot.Changed
CoreWindow.GetForCurrentThread().GetKeyState 変更なし。 これは AppWindow と DesktopWindowXamlSource でサポートされています。
CoreWindow.GetForCurrentThread().GetAsyncKeyState 変更なし。 これは AppWindow と DesktopWindowXamlSource でサポートされています。
Window.Current 現在の CoreWindow に緊密にバインドされているメイン XAML Window オブジェクトを返します。 この表の後の「注」を参照してください。
Window.Current.Bounds uiElement.XamlRoot.Size
Window.Current.Content UIElement root = uiElement.XamlRoot.Content
Window.Current.Compositor 変更なし。 これは AppWindow と DesktopWindowXamlSource でサポートされています。
VisualTreeHelper.FindElementsInHostCoordinates
UIElement パラメーターは省略可能ですが、Island でホストされているときに UIElement が指定されていないと、メソッドは例外を発生させます。
UIElement として uiElement.XamlRoot を指定し、空のままにしないでください。
VisualTreeHelper.GetOpenPopups
XAML Islands アプリでは、これによってエラーがスローされます。 AppWindow アプリでは、これによって、メインウィンドウに開いているポップアップが返されます。
VisualTreeHelper.GetOpenPopupsForXamlRoot(uiElement.XamlRoot)
FocusManager.GetFocusedElement FocusManager.GetFocusedElement(uiElement.XamlRoot)
contentDialog.ShowAsync() contentDialog.XamlRoot = uiElement.XamlRoot;
contentDialog.ShowAsync();
menuFlyout.ShowAt(null, new Point(10, 10)); menuFlyout.XamlRoot = uiElement.XamlRoot;
menuFlyout.ShowAt(null, new Point(10, 10));

注意

DesktopWindowXamlSource の XAML コンテンツの場合、スレッドに CoreWindow/Window が存在しますが、常に非表示で、サイズが 1x1 になります。 アプリから引き続きアクセスできますが、意味のある境界や表示対象は返されません。

AppWindow の XAML コンテンツの場合、同じスレッドには常に 1 つの CoreWindow が存在します。 GetForCurrentView または GetForCurrentThread API を呼び出すと、その API からは、そのスレッドで実行されている可能性のある AppWindows ではなく、スレッドの CoreWindow の状態を反映するオブジェクトが返されます。

推奨と非推奨

  • 「新しいウィンドウを開く」のグリフを利用することにより、セカンダリ ビューへの明確なエントリ ポイントを提供します。
  • セカンダリ ビューの目的をユーザーに伝えます。
  • アプリが単一のビューで完全に機能することを確認します。ユーザーは利便性のためにのみ、セカンダリ ビューを開きます。
  • 通知やその他の一時的な視覚効果を提供するためにセカンダリ ビューを使用しないようにします。