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

アプリの複数の独立した部分を別々のウィンドウで表示できるようにすることは、ユーザーが生産性を高めるために役立ちます。 そのわかりやすい例が、メイン UI に電子メールの一覧と選んだ電子メールのプレビューが表示される電子メールアプリです。 しかし、ユーザーはメッセージを別々のウィンドウで開き、並べて表示します。

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

ビューとは

アプリのビューは、スレッドとウィンドウが 1:1 で対応したもので、アプリがコンテンツの表示に使います。 ビューは Windows.ApplicationModel.Core.CoreApplicationView オブジェクトによって表現されます。

また、CoreApplication オブジェクトによって管理されます。 CoreApplication.CreateNewView を呼び出して、CoreApplicationView オブジェクトを作成できます。 CoreApplicationViewCoreWindowCoreDispatcher (CoreWindow プロパティと Dispatcher プロパティに格納) を関連付けます。 CoreApplicationView は、Windows ランタイムがコア Windows システムとのやり取りに使うオブジェクトとして考えることができます。

通常は CoreApplicationView を直接操作しません。 代わりに Windows ランタイムでは、ApplicationView クラスは Windows.UI.ViewManagement 名前空間にあります。 このクラスには、アプリがウィンドウ システムとのやり取りに使うプロパティ、メソッド、イベントが用意されています。 ApplicationView を操作するには、静的メソッド ApplicationView.GetForCurrentView を呼び出して、現在の CoreApplicationView のスレッドに関連付けられている ApplicationView インスタンスを取得します。

同様に、XAML フレーム ワークは CoreWindow オブジェクトを Windows.UI.XAML.Window オブジェクトにラップします。 XAML アプリでは通常、CoreWindow を直接操作しないで、Window オブジェクトを操作します。

新しいビューの表示

先に進む前に、新しいビューを作成する手順を見てみましょう。 ここでは、新しいビューがボタンのクリックに応じて起動されます。

private async void Button_Click(object sender, RoutedEventArgs e)
{
    CoreApplicationView newView = CoreApplication.CreateNewView();
    int newViewId = 0;
    await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        Frame frame = new Frame();
        frame.Navigate(typeof(SecondaryPage), null);   
        Window.Current.Content = frame;
        // You have to activate the window in order to show it later.
        Window.Current.Activate();

        newViewId = ApplicationView.GetForCurrentView().Id;
    });
    bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
}

新しいビューを表示するには

  1. CoreApplication.CreateNewView を呼び出して、ビュー コンテンツに使う新しいウィンドウとスレッドを作成します。

    CoreApplicationView newView = CoreApplication.CreateNewView();
    
  2. 新しいビューの Id を記録します。 これは後でビューの表示に使います。

    作成するビューの追跡に役立つ何らかのインフラストラクチャをアプリに構築することを検討することもできます。 例については、MultipleViews サンプルViewLifetimeControl クラスをご覧ください。

    int newViewId = 0;
    
  3. 新しいスレッドで、ウィンドウにコンテンツを読み込みます。

    CoreDispatcher.RunAsync メソッドを使って、UI スレッドでの新しいビューの操作をスケジュールします。 ラムダ式を使って、RunAsync メソッドの引数として関数を渡します。 ラムダ関数による操作は新しいビューのスレッドで実行されます。

    XAML では通常、WindowContent プロパティに Frame を追加した後、Frame から、アプリのコンテンツを定義した XAML Page に移ります。 詳しくは、「2 ページ間のピア ツー ピア ナビゲーション」をご覧ください。

    新しい Window にコンテンツが読み込まれたら、後で Window を表示するには、WindowActivate メソッドを呼び出す必要があります。 この操作は新しいビューのスレッドで実行されるため、新しい Window がアクティブになります。

    最後に、後でビューの表示に使う新しいビューの Id を取得します。 やはり、この操作も新しいビューのスレッドで実行されるため、ApplicationView.GetForCurrentView は新しいビューの Id を取得します。

    await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        Frame frame = new Frame();
        frame.Navigate(typeof(SecondaryPage), null);   
        Window.Current.Content = frame;
        // You have to activate the window in order to show it later.
        Window.Current.Activate();
    
        newViewId = ApplicationView.GetForCurrentView().Id;
    });
    
  4. ApplicationViewSwitcher.TryShowAsStandaloneAsync を呼び出して、新しいビューを表示します。

    新しいビューを作成したら、ApplicationViewSwitcher.TryShowAsStandaloneAsync メソッドを呼び出して、そのビューを新しいウィンドウに表示できます。 このメソッドの viewId パラメーターはアプリの各ビューを一意に識別する整数です。 ビュー Id は、ApplicationView.Id プロパティまたは ApplicationView.GetApplicationViewIdForWindow メソッドを使って取得できます。

    bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
    

メイン ビュー

アプリの起動時に最初に作成されるビューは、メイン ビューと呼ばれます。 このビューは、CoreApplication.MainView プロパティに格納され、その IsMain プロパティは true です。 このビューは作成しません。アプリによって作成されます。 メイン ビューのスレッドはアプリのマネージャーとして機能し、すべてのアプリの起動イベントはこのスレッドに振り分けられます。

セカンダリ ビューが開いている場合は、ウィンドウのタイトル バーの閉じるボタン (x) をクリックするなどして、メイン ビューのウィンドウを非表示にすることができます。ただし、そのスレッドはアクティブのままになります。 メイン ビューの WindowClose を呼び出すと、InvalidOperationException が発生します (Application.Exit を使ってアプリを閉じます)。メイン ビューのスレッドが終了した場合、アプリは終了します。

セカンダリ ビュー

アプリのコードで CreateNewView を呼び出すことで作成するすべてのビューなど、その他のビューがセカンダリ ビューです。 メイン ビューとセカンダリ ビューの両方が CoreApplication.Views コレクションに格納されます。 通常、ユーザーの操作に応じてセカンダリ ビューを作成します。 システムによってアプリのセカンダリ ビューが作成される場合もあります。

メモ

Windows の割り当てられたアクセス機能を使うと、キオスク モードでアプリを実行できます。 この場合、システムによってロック画面に、アプリの UI を表示するセカンダリ ビューが作成されます。 アプリによるセカンダリ ビューの作成は許可されないため、キオスク モードで独自のセカンダリ ビューを表示しようとすると、例外がスローされます。

ビュー間の切り替え

ユーザーには、セカンダリ ウィンドウからメイン ウィンドウに戻る方法を提供する必要があります。 そのためには、ApplicationViewSwitcher.SwitchAsync メソッドを使用します。 このメソッドを切り替え元のウィンドウのスレッドから呼び出し、切り替え先のウィンドウのビュー ID を渡します。

await ApplicationViewSwitcher.SwitchAsync(viewIdToShow);

SwitchAsync を使うときは、ApplicationViewSwitchingOptions の値を指定することで、最初のウィンドウを閉じてタスク バーから削除するかどうかを選べます。