ユニバーサルWindowsアプリの開発時に、WindowsストアアプリプロジェクトとWindows PhoneアプリプロジェクトでUI要素を共有する場合に考慮すべき点について取り上げる。
powered by Insider.NET
ユニバーサルプロジェクトを使ってユニバーサルWindowsアプリを開発するとき、真っ先に頭を悩ますのが「画面も共有できないだろうか?」という願望であろう。実際、共有プロジェクトに画面を追加することもできるし、「Build 2014」(ちなみに日本版の「de:code」は5月29〜30日開催)のキーノートではWindowsストアアプリの画面をそのままWindows Phoneで動かすというデモも行っていた。しかしながら、それは一般的にはあまり得策とはいえない。本稿では、筆者なりの指針を説明する。
ユニバーサルプロジェクトを使ってユニバーサルWindowsアプリを開発するには、以下の開発環境が必要である。本稿では、無償のVisual Studio Express 2013 for Windowsを使っている。
*1 SLAT対応ハードウェアは、Windows Phone 8.1エミュレーターの実行に必要だ。ただし未対応でも、ソースコードのビルドは可能だ。SLAT対応のチェック方法はMSDNブログの「Windows Phone SDK 8.0 ダウンロードポイント と Second Level Address Translation (SLAT) 対応PCかどうかを判定する方法」を参照。なお、SLAT対応ハードウェアであっても、VM上ではエミュレーターが動作しないことがあるのでご注意願いたい。
*2 事前には「Windows 8.1 Update 1」と呼ばれていたアップデート。スタート画面の右上に検索ボタンが(環境によっては電源ボタンも)表示されるようになるので、適用済みかどうかは簡単に見分けられる。ちなみに公式呼称は「the Windows RT 8.1, Windows 8.1, and Windows Server 2012 R2 update that is dated April, 2014」というようである。
*3 マイクロソフトのダウンロードページから誰でも入手できる。
*4 本稿に掲載した手順を試すだけなら、無償のExpressエディションで構わない。Visual Studio Express 2013 Update 2 for Windows(製品版)はマイクロソフトのページから無償で入手できる。Expressエディションはターゲットプラットフォームごとに製品が分かれていて紛らわしいが、Windowsストアアプリの開発には「for Windows」を使う(「for Windows Desktop」はデスクトップで動作するアプリ用)。
本稿では、紛らわしくない限り次の略称を用いる。
ユニバーサルプロジェクトは、共有プロジェクト・Windows用プロジェクト・Phone用プロジェクトの3つのプロジェクトから成っている(前回、および特集記事「Windowsストアアプリ開発最新情報(Build 2014より):ユニバーサルWindowsアプリ開発の勧め」参照)。そして、WindowsとPhoneのどちらのプロジェクトでもビルドできるソースならば、何でも共有プロジェクトに置くことが可能である。画面(=Windows.UI.Xaml.Controls名前空間のPageクラス)も共有プロジェクトに置けるのだ。
実際、共有プロジェクトに新しい項目を追加するためのダイアログボックス(次の画像)を見ると、[空白のページ]が用意されている。
そうなると、共有プロジェクトに画面も入れてしまいたくなる。そうすれば、Windows用プロジェクトとPhone用プロジェクトはほとんど空にすることも可能になる(プロジェクトファイルやマニフェストファイルなどを残すだけになる)。しかしそれは、非常に限定された場合だけにとどめておくのが無難である(次項で説明する)。
Build 2014のキーノートで、Windowsストアアプリのソースコードをユニバーサルプロジェクトに変換し、Windows用のコードをごっそりと共有プロジェクトに移し、Phoneアプリとしてもビルドして実行できるというデモを行っていた(次の画像)。
上の画像には、アプリ起動直後の画面が映っている。この画面には[戻る]ボタンのための左上の空白がない(移植前のWindowsストアアプリにもなかった)。だから簡単に移植できたのだ。
[戻る]ボタンの扱いは、WindowsとPhoneで異なっている。Windowsでは、画面の左上に[戻る]ボタンを開発者が配置し、そのイベントハンドラーを書く。Phoneでは、物理的な[戻る]ボタンがあり、開発者はシステム側で発生する割り込みに対処するコードを書く(物理的な[戻る]ボタンがない機種でも同様)。1つの画面定義で両方に対応するには、WindowsとPhoneで[戻る]ボタン周りのレイアウトを切り替えることと、それぞれのイベント(Windowsではボタンのクリックイベント、PhoneではOSからの割り込みに対するイベント)に対処する必要がある*5。上述したキーノートのデモでは、[戻る]ボタンがなかったのでそれらの修正も行わずに済んだのである。
従って、[戻る]ボタンを持たないごく簡単な1画面だけのアプリならば、画面を共有プロジェクトに置いてもよさそうである*6。
*5 Commonフォルダーに自動生成される「NavigationHelper」クラスに、Phoneの[戻る]ボタンへの対応がUpdate 2で追加されている。この新しい「NavigationHelper」クラスを利用する場合には、画面レイアウトの切り替えだけを実施すればよい。
*6 [戻る]ボタンを持つ画面を共有プロジェクトに置くことも可能ではある。後述する「クラウディアさんタイマーVer.2」では、ヘルプ画面(「HelpPage.xaml」ファイル)を試みに共有プロジェクトに置いてみた。そのために、Windows用の画面をベースとして、[戻る]ボタンをテンプレートのButtonコントロールからAppBarButtonコントロール(ともにWindows.UI.Xaml.Controls名前空間)に置き換えた(Buttonコントロールのままでは、Phone側で「スタイル定義がない」というエラーになる)。また、コードビハインドには[戻る]ボタンの表示を切り替えるコードを追加した。しかし、そのような手間を掛けるくらいなら、後述するユーザーコントロールにした方がよほど楽だし、分かりやすい。
これが王道であろう。大規模な開発などでMVVMアーキテクチャを採用していれば、自然とそうなるはずだ(次の図)。また、規模に関係なく、画面を厳密にレイアウトしたい場合は、WindowsとPhoneで別々に画面を作ることになるだろう(後述)。
折衷案として、ユーザーコントロールを使うのはどうだろうか? 画面の主要な部分をユーザーコントロールに作り込んで、それをWindowsとPhoneそれぞれの画面に貼り付けるのだ。画面のレイアウトに厳密さが要求されないのなら、これは有効な方法だ。
例として、筆者が公開しているユニバーサルWindowsアプリの画面を紹介しよう*7。次の画像は、メイン画面だ。赤枠の部分をユーザーコントロールとして共有プロジェクトに作ってある。
*7 ユニバーサルWindowsアプリ「クラウディアさんタイマーVer.2」(Windows用、Phone用)。そのソースコードは、Windows Store app samples:クラウディアさんタイマー (Claudia Madobe Timer) Ver.2で公開している。
また、次の画像はオプション設定パネルだ。赤枠の部分をユーザーコントロールとして共有プロジェクトに作ってあるのは同じだが、WindowsではそれをSettingsFlyoutコントロール(Windows.UI.Xaml.Controls名前空間)のコンテンツにしている。
上の画像で、オプション設定パネル左下のロゴ画像と右下の[レビュー]ボタンの位置関係に注目してほしい(次の画像)。Windowsでは下端がだいたいそろっているのに、Phoneではズレてしまっている。このような違いが許容できるなら、ユーザーコントロールで画面コンテンツを共有できる*8。
*8 WindowsとPhoneのスタイル定義を作り込むことで、細部までレイアウトを一致させることは可能かもしれない。しかし、そこに労力を注ぎ込むくらいなら、別々の画面として、むしろVとVMの分離に力を使うべきだと筆者は考える。
ユニバーサルプロジェクトで開発するとき、画面を共有するかどうかは次のように考えるとよいだろう。
また、画面によって置き場所を変えることも考えられる。例えば、メイン画面はレイアウトを厳密にしたいから共有しないが、ヘルプ画面はアバウトでも構わないのでユーザーコントロールを共有に置く、などである。
5月29日(木)〜5月30日(金)、マイクロソフトの最新技術情報(例えば本稿で解説したような内容)を日本語で日本人向けに提供するカンファレンス「de:code」が日本マイクロソフト主催で開催される。このカンファレンスは、米国時間で4月2〜4日に開催された「Build 2014」の内容をベースに、さらに日本向けのプラスアルファを含めたものになる。詳しい内容は(セッション内容は開催日までに決定していくとのこと)、リンク先を参照されたい。
Copyright© Digital Advantage Corp. All Rights Reserved.