Windows 8から8.1への更新で、面倒だったアプリ・バーの実装がより手軽になった。新たに用意されたコントロールを使う方法を説明する。
powered by Insider.NET
Windowsストア・アプリにアプリ・バーを実装するのは、Windows 8(以降、Win 8)ではかなり面倒だった。丸いコマンド・ボタンを作るだけでも、「WinRT/Metro TIPS:アプリ・バーの四角いボタンを丸くするには?[Win 8]」で解説したように、結構な手間と知識が必要だ。さらに、ビューの幅が狭いときはコンパクトな表示にしたいとか、タップ時にフライアウトを出したいなどと思うと、ちょっと遠慮したくなるレベルで煩雑な実装が要求される。何とかならないだろうか?
Windows 8.1(以降、Win 8.1)用のWindowsストア・アプリ(以降、Win 8.1アプリ)のために新しく用意されたアプリ・バーのためのコントロールが、それらの問題を解決してくれる。本稿では、それらの新しいコントロールを使う方法を解説する*1。本稿のサンプルは「Windows Store app samples:MetroTips #53(Windows 8.1版)」からダウンロードできる。
*1 本稿はPreview版に基づいて記述しているため、製品版では異なる可能性がある。あらかじめご承知おきいただきたい。なお、本稿の内容は、「特集:次期Windows 8.1&Visual Studio 2013 Preview概説(後編):大きく変わるWindowsストア・アプリ開発 〜 そのほかの変更点 (3/4)」でも簡単に紹介している。併せてお読みいただければ幸いである。
Win 8.1アプリを開発するには、Win 8.1とVisual Studio 2013(以降、VS 2013)が必要である。本稿執筆時点ではまだ製品版は一般公開されておらず、本稿ではOracle VirtualBox上で64bit版Windows 8.1 Pro PreviewとVisual Studio Express 2013 Preview for Windowsを使用している。これらを準備する方法や注意事項は、「WinRT/Metro TIPS:Win8用のソース・コードをWin8.1用に変換するには?[Win 8.1]」の記事をご参照いただきたい。
AppBarButtonコントロール(Windows.UI.Xaml.Controls名前空間)を使う。
円内の絵はAppBarButtonコントロールのIconプロパティ(=Windows.UI.Xaml.Controls名前空間のIconElementクラス)に指定し、円の下の文字列はLabelプロパティに指定する。また、IsCompactプロパティにtrue/Trueをセットすると、円の下の文字列が消え、円もやや小さくなって、コントロールの占有サイズが小さくなる。
IconプロパティにはIconElementクラスのオブジェクトを設定するのだが、通常はIconElementクラスを継承した次の4つのいずれかを使用する(いずれも、Windows.UI.Xaml.Controls名前空間)。
クラス名 | 説明 |
---|---|
SymbolIcon | Symbol列挙体(Windows.UI.Xaml.Controls名前空間)を使って指定する。「Segoe UI Symbol」フォントのグリフの定義済みの一覧に基づく。 VS 2013のプロパティ・ペインでは、ドロップダウンから選択できる。ドロップダウンにはグリフも表示されており、目的のグリフを探しやすい |
FontIcon | 指定されたフォント・ファミリのグリフに基づく。文字は直接指定してもよいし、文字コードでも指定できる |
BitmapIcon | 指定されたURIのビットマップ画像ファイルに基づく |
PathIcon | 指定されたPathオブジェクト(Windows.UI.Xaml.Shapes名前空間)に基づく。 XAMLでは「パス・マークアップ構文」を用いてPathオブジェクトを生成できる(次のサンプル・コードで使用している記法) |
Iconプロパティに設定できる4種類のオブジェクト |
上の画像のAppBarButtonコントロールは、この表の順に並んでいる。そのコードは次のようになる。
<Page.BottomAppBar>
<!-- AppBarコントロールを使ったアプリ・バー-->
<AppBar Background="#cc080010">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- 左側のコマンド・ボタン群 -->
<StackPanel Orientation="Horizontal">
<!-- SymbolIcon -->
<AppBarButton Label="Symbol">
<AppBarButton.Icon>
<SymbolIcon Symbol="Forward" />
</AppBarButton.Icon>
</AppBarButton>
<!-- SymbolIconの場合は次のように略記できる -->
<!--<AppBarButton Icon="Forward" Label="Symbol" />-->
<!-- FontIcon -->
<AppBarButton Label="FontIcon" >
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe UI Symbol" Glyph=""/>
</AppBarButton.Icon>
</AppBarButton>
<!-- BitmapIcon -->
<AppBarButton Label="BitmapIcon" >
<AppBarButton.Icon>
<BitmapIcon UriSource="Assets/Logo.png"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- PathIcon -->
<AppBarButton Label="PathIcon" >
<AppBarButton.Icon>
<PathIcon Data="F1 M 20,20L 24,10L 24,24L 5,24"/>
</AppBarButton.Icon>
</AppBarButton>
</StackPanel>
<!-- 右側のコマンド・ボタン群 -->
<StackPanel Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Right">
……省略……
</StackPanel>
</Grid>
</AppBar>
</Page.BottomAppBar>
コマンド・ボタンを配置するアプリ・バーは、上のコードのようにしてそのレイアウトを定義するのがWin 8アプリでは一般的であった。すなわち、AppBarコントロールの中にGridコントロールを置き、そのグリッドを左右に分割し、それぞれにStackPanelコントロールを置いて、その中にコマンド・ボタンを配置するという手間を掛けていた。Win 8.1アプリでは、上述したように丸いコマンド・ボタンをAppBarButtonコントロールで簡単に作れるようになっただけでなく、新しいコントロールを使うことでこの面倒なレイアウト作業も楽にできる。後ほど「コマンド・ボタンの間隔を調整するには?」の項で説明する。
トグル・ボタンとは、1回タップするとONになり、もう1回タップするとOFFになるボタンだ。アプリ・バーのコマンド・ボタンでトグル動作を実装するには、AppBarToggleButtonコントロール(Windows.UI.Xaml.Controls名前空間)を使う。IconプロパティとLabelプロパティの設定方法は、前述のAppBarButtonコントロールと同じだ。
コマンド・ボタンをグループ分けするためのセパレータ(=縦の分割線)には、AppBarSeparatorコントロール(Windows.UI.Xaml.Controls名前空間)を使う。AppBarSeparatorコントロールにIconプロパティとLabelプロパティは無いが、IsCompactプロパティはある。
AppBarButtonコントロールのFlyoutプロパティ(=Windows.UI.Xaml.Controls.Primitives名前空間のFlyoutBaseクラス)にフライアウトを設定する。
Flyoutプロパティは、Win 8.1アプリ用に新設されたもので、Windows.UI.Xaml.Controls名前空間のButtonコントロール(および、それを継承したコントロール)が持っている。Flyoutプロパティに設定できるのは、FlyoutBaseクラスを継承しているFlyoutコントロールかMenuFlyoutコントロール(ともに、Windows.UI.Xaml.Controls名前空間)である。どちらも、Flyoutプロパティに設定するだけで、ボタンのタップ時に自動的にフライアウトが出てくるようになる。
まず、MenuFlyoutコントロールであるが、これはメニューに特化したフライアウトで、次のコードのようにメニュー項目としてMenuFlyoutItemコントロールまたはToggleMenuFlyoutItemコントロール(ともにWindows.UI.Xaml.Controls名前空間)を設定するだけだ。メニュー項目がタップされると、フライアウトは自動的に閉じる。また、メニュー項目をグループ化するためにMenuFlyoutSeparatorコントロール(Windows.UI.Xaml.Controls名前空間)が使える。なお、次のコードには記述していないが、メニュー項目がタップされたときのイベント・ハンドラは各メニュー項目のTapped属性に指定する。
<AppBarButton Label="……省略……" >
<AppBarButton.Icon>
……省略……
</AppBarButton.Icon>
<!-- メニュー専用のフライアウト -->
<AppBarButton.Flyout>
<MenuFlyout>
<MenuFlyoutItem Text="メニュー1" />
<MenuFlyoutItem Text="メニュー2" />
<MenuFlyoutSeparator />
<ToggleMenuFlyoutItem Text="メニュー3(トグル)" />
</MenuFlyout>
</AppBarButton.Flyout>
</AppBarButton>
これを実行すると、次の画像のようになる。
次に、Flyoutコントロールは汎用的なフライアウトだ。その内容は自由に実装できる。次のコードでは、文字列と[OK]/[CANCEL]ボタンを持たせてみた。なお、MenuFlyoutコントロールとは異なり、ボタンをタップしてもFlyoutコントロールは閉じないので、必要ならば自前でFlyoutコントロールを閉じるコードを実装する(ボタンのイベント・ハンドラ中にフォーカスを移すことになる処理、例えばメッセージボックスを出す処理などがあれば自動的に閉じる)。
<AppBarButton Label="……省略……" >
<AppBarButton.Icon>
……省略……
</AppBarButton.Icon>
<!-- 汎用的なフライアウト -->
<AppBarButton.Flyout>
<Flyout>
<StackPanel>
<TextBlock Text="実行します" FontSize="15" HorizontalAlignment="Center" />
<StackPanel Orientation="Horizontal">
<Button Content="OK" Width="100" />
<Button Content="CANCEL" Width="100" />
</StackPanel>
</StackPanel>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
これを実行すると、次の画像のようになる。
Win 8.1アプリではビューの最小幅はデフォルトで500pxであり、最小幅ではコマンド・ボタンが5個を超えると全てを表示できなくなる。例えば、左側に6個、右側に2個、合計8個のコマンド・ボタンを配置すると次の画像のようになる。
これを解決するには、ビューの幅を見て、コマンド・ボタンのIsCompactプロパティを全てfalse/Falseに切り替えてやればよいのだが、それは面倒だ。何とかならないだろうか?
コマンド・ボタンだけを持つシンプルなアプリ・バーの場合には、AppBarコントロールの代わりにCommandBarコントロール(ともにWindows.UI.Xaml.Controls名前空間)を利用すればよい。次のコードのようにとても簡潔に書ける。
<!-- CommandBarコントロールを使ったアプリ・バー-->
<Page.BottomAppBar>
<CommandBar Background="#cc080010">
<!-- 左側のコマンド・ボタン群 -->
<CommandBar.SecondaryCommands>
<AppBarButton Icon="Back" Label="戻る" />
……省略(ボタン5個)……
</CommandBar.SecondaryCommands>
<!-- 右側のコマンド・ボタン群 -->
<CommandBar.PrimaryCommands>
<AppBarToggleButton Label="オプション" Icon="Flag" />
<AppBarButton Icon="Help" Label="ヘルプ" />
</CommandBar.PrimaryCommands>
</CommandBar>
</Page.BottomAppBar>
CommandBarコントロールには、コマンド・ボタンを配置できるエリアが左右に2つ用意されている。右側がPrimaryCommandsプロパティで、左側がSecondaryCommandsプロパティだ。AppBarコントロールでは、その内部にGridコントロールやStackPanelコントロールなどを配置してコマンド・ボタンのレイアウトを構成する必要があったが、CommandBarコントロールではPrimaryCommands/SecondaryCommandsプロパティにコマンド・ボタンを記述するだけで済む。そして、ビューの幅が十分にあるときはAppBarコントロールの場合と同様に表示され、ビューの幅が狭いときは自動的にコンパクトな表示に変えてくれるのだ(次の画像)。
なお、CommandBarコントロールは、全てのコマンド・ボタンを表示しきれなくなったときには、SecondaryCommands(左側のコマンド・ボタン群)が表示されなくなる。
Win 8.1アプリのために新しく用意されたコントロールを活用すると、アプリ・バーの実装が楽になるだけでなく、ボタンのタップ時にフライアウトを出すことも非常に簡単にできる。
Copyright© Digital Advantage Corp. All Rights Reserved.