8.1で複数のウィンドウを表示できるようになった。その実装方法を解説する。Insider.NET連載目次Windowsストアは原則として1アプリに1ウィンドウである。1つのアプリからモニターとプロジェクターに異なる画面を表示したいとき。コンテンツを表示するウィンドウを複数出したいときなどだ。8.1)ではそれが可能になった。本稿ではその方法を解説する。#71」からダウンロードできる。2013)が必要である。Windows(日本語版)*2を使用している。Update(2014年4月)を適用済み。このアップデートは必須とされている。Windows」から無償で入手できる。Explorer(以降、IE)がある(厳密にはWindowsストアアプリではない)。次の画像のように、複数のウィンドウを開くことができる。IEで新しいウィンドウを開くこの画像のモニターは1920×1080ピクセルであり、横3つのウィンドウに分割している。そのうち2つのウィンドウには、すでにIEが開かれている。8.1のIEでは、例えばリンク先のページを開くときに新しいウィンドウを作成できる。それには、(1)リンクを長押し/右クリックしてメニューを出し(タッチではアプリバーが、マウスでは画像のようにコンテキストメニューが出てくる)、(2)メニューから[リンクを新しいウィンドウで開く]を選ぶと、(3)画面が分割されて新しくウィンドウが作られ(または、すでに最大限まで分割済みの場合は既存のウィンドウに)リンク先のページが表示される。8.1では、上で紹介したIEのように複数のウィンドウを表示し、また、アプリからウィンドウ(アプリビュー)*3を切り替えるための新しいAPIが用意された。CoreApplicationクラス(Windows.ApplicationModel.Core名前空間)に新設されたCreateNewViewメソッドで新しいウィンドウ(アプリビュー)を作る。新設されたApplicationViewSwitcherクラス(Windows.UI.ViewManagement名前空間)のメソッドを使って、現在のウィンドウの中身を切り替える(SwitchAsyncメソッド)、あるいは、隣接するウィンドウに表示する(TryShowAsStandaloneAsyncメソッド)。一般的なコードの流れは、次のようになるだろう。CreateNewViewメソッドで新しいウィンドウ(アプリビュー)を作る新しいウィンドウ(アプリビュー)にコンテンツ(一般にはFrameコントロール)をセットし、表示したいページにナビゲートするApplicationViewSwitcherクラスのメソッドで表示を切り替える以降で、具体的なコードを紹介していく。MSDNでは画面分割に関して、ウィンドウとアプリビューを文章の上できちんと区別していない。インスタンス」などと同一視して書かれている。実際には、ウィンドウはWindowクラス(Windows.UI.Xaml名前空間)、アプリビューはApplicationViewクラス(Windows.UI.ViewManagement名前空間)であり、これらは別のものである。WindowクラスとApplicationViewクラスをきちんと分けて理解しないと、複数ウィンドウ表示のプログラミングは難しい。画面に表示するコンテンツ(一般にはFrameコントロール(Windows.UI.Xaml.Controls名前空間)およびその中に配置された複数のコントロール)を格納するのがWindowクラスで、そのWindowクラスをどのようにモニターに表示するかを調整するのがApplicationViewクラスだと考えてほしい。Windowクラスは目に見えるUIを持つのでInspectツールに表示されるが、ApplicationViewクラスはUIを持たないので表示されない。2つ目のウィンドウを開くには?これだけではあまり実用的ではないが、まずは理解のために、2つ目のウィンドウを開くだけのコードを考えてみよう。アプリ起動時に表示される画面は「MainPage.xaml」ファイルに定義されていて、2つ目のウィンドウに表示したい画面は「SecondaryPage.xaml」ファイルに定義されているものとする。「MainPage.xaml」にクリックイベントを持つ何らかのコントロールを配置し、そのイベントハンドラーに次のようなコードを記述する(コメント中の数字は上記の手順1.〜3.に対応する)。Windows.UI.ViewManagement.ApplicationViewSwitcher.TryShowAsStandaloneAsync(viewId)2つ目のウィンドウを開くだけのコード(上:C#、下:VB)コード中でawait/Awaitキーワードを使っているので、イベントハンドラーのシグネチャにはasync/Asyncキーワードが必要だ。前述した一般的なコードの流れに付けた番号を、コメントにも付けてある(ただし、「2」は「2a」と「2b」に分割)。ウィンドウを表示するだけなら、「2a」ではApplicationViewオブジェクトのIdを保持するだけでよい(「3」で必要なのはIdだけであるから)。「Dispatcher.RunAsync」などと出てきて面食らうかもしれないが、前述した一般的なコードの流れのうち2番目の処理は、新しく生成したウィンドウ(アプリビュー)のスレッドで行う必要があるのだ。取得できるApplicationViewオブジェクトとWindowオブジェクトは、コードを実行しているスレッドに結び付いているからだ。別途公開しているサンプルコードにはちょっとしたUIが作り込んである。そこで上のコードを実行すると次の画像のようになる。単純に「SecondaryPage」を新しいウィンドウに開く上:2つ目のウィンドウを開いたところ。左側が「MainPage」、右側が「SecondaryPage」。引数が1つのTryShowAsStandaloneAsyncメソッドは、このように画面を等分割して新しいウィンドウを開く。中:それぞれのウィンドウは独立しているから、それぞれ違うアプリに切り替えられる。左側はIE、右側が本サンプル。下:前述のコードは、単純に「SecondaryPage」を新しいウィンドウに開くだけであるから、実行するたびに「SecondaryPage」のウィンドウが増えていく。画像では、左端から引き出したタスク一覧が「SecondaryPage」で埋め尽くされている。複数のウィンドウを管理するには?上の画像のように新しいウィンドウが増え続けるのは、困る場合もあるだろう。コードからウィンドウ(アプリビュー)を切り替えたいこともあるだろう。それには、ApplicationViewオブジェクトのIdを管理すればよい。そのような管理をする場所としては、「App」クラスが適切だ。画面は、どの画面であれ、複数表示する可能性があるからだ。ApplicationView>」クラスのオブジェクトをメンバー変数として配置し、作成したApplicationViewオブジェクトを格納しておくようにする。ウィンドウを切り替えようとしたときに、まだApplicationViewオブジェクトが存在していない場合だけ新しいウィンドウ(アプリビュー)を作成するようにする。これで冒頭に挙げた希望がかなう。存在しないウィンドウ(アプリビュー)なので、作成する。存在しないウィンドウ(アプリビュー)なので、作成する。Function同じウィンドウは開かないようにするコード(上:C#、下:VB)省略したCreateKeyStringメソッドでは、引数の組み合わせごとに異なる文字列を返すように実装する。すると、「MainPage」から上記ShowSecondaryViewAsyncメソッドを2回以上呼び出すとき、引数が同じなら既存のウィンドウ(アプリビュー)に切り替わるだけとなり、また、引数が以前と違っていれば新しいウィンドウ(アプリビュー)が作られて表示されることになる。その他に、エンドユーザーの利便性を考えるなら前回紹介したようにタイトルバーに文字列を設定して、複数のウィンドウを識別できるようにしておこう。ApplicationViewオブジェクトには「Consolidated」というイベントがある。これはエンドユーザーがそのウィンドウを閉じたときに発生するものだ(タイトルバーの[X]ボタン、または上端から下端までのスライドによって)。複数のウィンドウに情報を伝達するには?それぞれのウィンドウ(アプリビュー)は、異なるUIスレッドで動作している。そこで、情報伝達には主にイベントを利用することになる。「App」クラスに次のコードのようなイベントを用意しておく。String)「App」クラスにイベントを用意する(上:C#、下:VB)それぞれの画面では、初期化時に上のイベントにハンドラーを結び付けて情報を受け取る(次のコード)。Sub画面では「App」クラスのイベントにハンドラーを結び付けて情報を受け取る(上:C#、下:VB)ここでは、イベントで受け取った文字列を、画面に配置したTextBlockコントロール(名前は「MessageTextBlock」)に表示している。これで、「App」クラス内から「MessageEvent」イベントを発火してやれば、表示されている全ての画面に情報が伝達される。以上の内容が別途公開のサンプルコードに全て実装されている(次の画像)。別途公開のサンプルコードを実行しているところこの画像のモニターは1920×1080ピクセルである。「SecondaryPage」のウィンドウは最大2つまで表示できる。Window」とウィンドウ中央に表示されている。ウィンドウを開く/閉じるごとに、全てのウィンドウに共通のメッセージが表示される。タイトルバーには、ウィンドウごとに異なる文字列が設定されている。まとめWindowオブジェクトとApplicationViewオブジェクトの関係と、それらが同時に(しかも間接的に)生成されることが理解できれば、複数のウィンドウ(アプリビュー)を表示することは意外と簡単だ。ウィンドウ(アプリビュー)ごとにUIスレッドが異なる点には要注意である。複数のウィンドウ(アプリビュー)表示については、次のドキュメントも参照してほしい。MSDN:複数のウィンドウのガイドライン本稿で説明しなかったプロジェクターへの表示については、次のドキュメントを参照してほしい。8.1を扱う大規模カンファレンスのご紹介5月29日(木)〜5月30日(金)、マイクロソフトの最新技術情報(例えば本稿で解説したような内容)を日本語で日本人向けに提供するカンファレンス「de:code」が日本マイクロソフト主催で開催される。2014」の内容をベースに、さらに日本向けのプラスアルファを含めたものになる。詳しい内容は(セッション内容は開催日までに決定していくとのこと)、リンク先を参照されたい。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。