スタート画面に表示されるアプリのタイルは、そのアプリにより増やせる。アプリで2つ目以降のタイルは「セカンダリ・タイル」と呼ばれる。その作成方法を説明する。
powered by Insider.NET
スタート画面に表示されるアプリのタイルは、そのアプリにより増やすことができる。アプリで2つ目以降のタイルを「セカンダリ・タイル」と呼ぶ。そして、セカンダリ・タイルからアプリの特定のページや検索結果などが直接開くようなプログラムを作ることが可能だ。エンド・ユーザー(以降、ユーザー)は「スタート画面にピン留めする*1」コマンドで、この機能を利用できる。本稿では、そのようなセカンダリ・タイルを活用する方法を説明する。本稿のサンプルは「Windows Store app samples:MetroTips #23」からダウンロードできる。
*1 英語のアプリでの表記は、「Pin to Start」/「Unpin from Start」。日本語のアプリでは「スタート画面にピン留めする」/「スタート画面からピン留めを外す」が推奨されているが、そのような長い文字列をコマンド・ボタンの下に表示すると改行されてしまうため、「ピン留めする」/「ピン留め解除」などと略記しているアプリもある。
●事前準備
Windows 8(以降、Win8)向けのWindowsストア・アプリを開発するには、Win 8とVisual Studio 2012(以降、VS 2012)が必要である。これらを準備するには、第1回のTIPSを参考にしてほしい。本稿では64bit版Win 8 ProとVS 2012 Express for Windows 8を使用している。
●セカンダリ・タイルを作成するには?
SecondaryTileクラス(Windows.UI.StartScreen名前空間)のオブジェクトを作り、ユーザーにピン留めの許可を求めるリクエストを発行すればよい。
まず、SecondaryTileクラスをインスタンス化し、必要なパラメータをセットする。次に挙げるのは必須のパラメータ(厳密にはSecondaryTileクラスのプロパティ)だ。
【必須のパラメータ】
そうしたらSecondaryTileクラスのRequestCreateForSelectionAsyncメソッドを呼び出す。コードとしてはこれだけである(次のコード)。
private async Task<bool> CreateSecondaryTile(Rect buttonArea)
{
var secondaryTile = new Windows.UI.StartScreen.SecondaryTile() {
TileId = "Test", // 【必須】タイルを識別するID。削除時にも使う
ShortName = "TIP#23 2nd", // 【必須】タイルに表示される短い名前
DisplayName = "WinRT/Metro TIPS #23 - 2nd tile", // 【必須】アプリの長い名前
Arguments = "試験です", // 【必須】起動時に渡される引数
TileOptions // 省略可
= Windows.UI.StartScreen.TileOptions.ShowNameOnLogo
| Windows.UI.StartScreen.TileOptions.ShowNameOnWideLogo,
Logo = new Uri("ms-appx:///Assets/Logo.png"), // 【必須】
WideLogo = new Uri("ms-appx:///Assets/WideLogo.png"), // 【オプション】
// ※既定のワイド・ロゴがなくても、セカンダリにワイド・ロゴが設定できる
BackgroundColor
= Windows.UI.Color.FromArgb(0xff, 0x0, 0xA2, 0xE8), // 【オプション】
ForegroundText
= Windows.UI.StartScreen.ForegroundText.Light, // 【オプション】
};
bool isPinned
= await secondaryTile.RequestCreateForSelectionAsync(
buttonArea, Windows.UI.Popups.Placement.Above);
return isPinned;
}
Private Async Function CreateSecondaryTile(buttonArea As Rect) _
As Task(Of Boolean)
Dim secondaryTile = New Windows.UI.StartScreen.SecondaryTile()
With secondaryTile
.TileId = "Test" ' 【必須】タイルを識別するID。削除時にも使う。
.ShortName = "TIP#23 2nd VB" ' 【必須】タイルに表示される短い名前。
.DisplayName = "WinRT/Metro TIPS #23 - 2nd tile (VB)" ' 【必須】アプリの長い名前。
.Arguments = "試験です" ' 【必須】起動時に渡される引数。
.TileOptions _
= Windows.UI.StartScreen.TileOptions.ShowNameOnLogo _
Or Windows.UI.StartScreen.TileOptions.ShowNameOnWideLogo ' 省略可
.Logo = New Uri("ms-appx:///Assets/Logo.png") ' 【必須】
.WideLogo = New Uri("ms-appx:///Assets/WideLogo.png") ' 【オプション】
' ※既定のワイド・ロゴがなくても、セカンダリにワイド・ロゴが設定できる
.BackgroundColor _
= Windows.UI.Color.FromArgb(&HFF, &H0, &HA2, &HE8) ' 【オプション】
.ForegroundText _
= Windows.UI.StartScreen.ForegroundText.Light ' 【オプション】
End With
Dim IsPinned As Boolean _
= Await secondaryTile.RequestCreateForSelectionAsync( _
buttonArea, Windows.UI.Popups.Placement.Above)
Return IsPinned
End Function
このメソッドのRect型の引数「buttonArea」には、タップされたコマンド・ボタンの場所を渡す(場所を取得するコードは後述)。そしてメソッドを呼び出すと、コマンド・ボタンのすぐ上に次の画像のようなポップアップが表示される。
ここでユーザーが[スタート画面にピン留めする]をタップすると、実際にセカンダリ・タイルが作成され、RequestCreateForSelectionAsyncメソッドの戻り値はtrueになる。タップしなければ、セカンダリ・タイルは作成されず、メソッドはfalseを返す。また、ユーザーはこのポップアップで、タイルに表示される短い名前を自由に変更できる。
●セカンダリ・タイルを削除するには?
ユーザーはスタート画面でいつでもセカンダリ・タイルを削除できる。コードから削除するには、ユーザーにピン留め解除の許可を求めるリクエストを発行すればよい。
それは次のようなメソッドになる。削除対象のセカンダリ・タイルを識別するためにTileIdを使う。
private async Task<bool> RemoveSecondaryTile(Rect buttonArea)
{
var secondaryTile
= new Windows.UI.StartScreen.SecondaryTile("Test"); // 引数はTileId
bool isUnpinned
= await secondaryTile.RequestDeleteForSelectionAsync(
buttonArea, Windows.UI.Popups.Placement.Above);
return isUnpinned;
}
Private Async Function RemoveSecondaryTile(buttonArea As Rect) _
As Task(Of Boolean)
Dim secondaryTile _
= New Windows.UI.StartScreen.SecondaryTile("Test") ' 引数はTileId
Dim isUnpinned As Boolean _
= Await secondaryTile.RequestDeleteForSelectionAsync( _
buttonArea, Windows.UI.Popups.Placement.Above)
Return isUnpinned
End Function
メソッドの引数には、前と同様にタップされたコマンド・ボタンの場所を渡す。メソッドを呼び出すと、画面には次の画像のようなポップアップが表示される。
ここでユーザーが「スタート画面からピン留めを外す」をタップすると、実際にセカンダリ・タイルが削除されメソッドの戻り値はtrueになる。そうでなければ、削除されず戻り値はfalseになる。
なお、存在しないTileIdを使ってRequestDeleteForSelectionAsyncメソッドを呼び出してもエラーにはならず、ポップアップも表示されることなく直ちにfalseが返ってくる。
●「スタート画面にピン留め」コマンドを実装するには?
アプリ・バーのコマンド・ボタンで上記のメソッドを呼び出すようにすればよい。
セカンダリ・タイルを作成・削除するUIは、「MSDN:セカンダリ タイルのガイドラインとチェック リスト」によると、アプリ・バーに「スタート画面にピン留め」コマンドとして実装するように要請されている。また、セカンダリ・タイル表示中には、同じボタンが「スタート画面からピン留めを外す」に変わるようにしなければならない。
コマンド・ボタンを切り替える方法はいくつかあるが、ここでは2つ配置しておいて片方を隠すようにしてみよう。まずは(次の画像とコードのように)VS 2012のXAMLデザイナでアプリ・バーとコマンド・ボタンをデザインする。
<Button x:Name="buttonPin" Click="buttonPinClicked"
Style="{StaticResource PinAppBarButtonStyle}"
AutomationProperties.Name="ピン留めする" />
<Button x:Name="buttonUnpin" Click="buttonUnpinClicked"
Style="{StaticResource UnPinAppBarButtonStyle}"
AutomationProperties.Name="ピン留め解除" />
なお、コマンド・ボタンに適用した2つのスタイル(=「PinAppBarButtonStyle」と「UnPinAppBarButtonStyle」)は、「StandardStyles.xaml」ファイルにコメントとして記述されているので、コメントを外して使う。
次に、コマンド・ボタンの表示を切り替えるメソッドを記述する。
private void ToggleAppBarButton(bool isPinned)
{
if (isPinned)
{
buttonPin.Visibility = Visibility.Collapsed;
buttonUnpin.Visibility = Visibility.Visible;
}
else
{
buttonPin.Visibility = Visibility.Visible;
buttonUnpin.Visibility = Visibility.Collapsed;
}
}
Private Sub ToggleAppBarButton(isPinned As Boolean)
If (isPinned) Then
buttonPin.Visibility = Visibility.Collapsed
buttonUnpin.Visibility = Visibility.Visible
Else
buttonPin.Visibility = Visibility.Visible
buttonUnpin.Visibility = Visibility.Collapsed
End If
End Sub
画面が表示されたときに、このメソッドを呼び出して片方のボタンを隠す。ページのLoadStateメソッドに次のコードを追加する。
ToggleAppBarButton(IsPinned("Test"));
ToggleAppBarButton(IsPinned("Test"))
最後に、コマンド・ボタンがタップされたときのイベント・ハンドラを実装する(次のコード)。
private async void buttonPinClicked(object sender, RoutedEventArgs e)
{
pageRoot.BottomAppBar.IsSticky = true;
bool isPinned =
await CreateSecondaryTile(GetElementRect((FrameworkElement)sender));
ToggleAppBarButton(isPinned);
pageRoot.BottomAppBar.IsSticky = false;
}
Private Async Sub buttonPinClicked(sender As Object, e As RoutedEventArgs)
pageRoot.BottomAppBar.IsSticky = True
Dim isPinned As Boolean _
= Await CreateSecondaryTile( _
GetElementRect(DirectCast(sender, FrameworkElement)))
ToggleAppBarButton(isPinned)
pageRoot.BottomAppBar.IsSticky = False
End Sub
private async void buttonUnpinClicked(object sender, RoutedEventArgs e)
{
pageRoot.BottomAppBar.IsSticky = true;
bool isUnpinned
= await RemoveSecondaryTile(GetElementRect((FrameworkElement)sender));
ToggleAppBarButton(!isUnpinned);
pageRoot.BottomAppBar.IsSticky = false;
}
Private Async Sub buttonUnpinClicked(sender As Object, e As RoutedEventArgs)
pageRoot.BottomAppBar.IsSticky = True
Dim isUnpinned As Boolean _
= Await RemoveSecondaryTile( _
GetElementRect(DirectCast(sender, FrameworkElement)))
ToggleAppBarButton(Not isUnpinned)
pageRoot.BottomAppBar.IsSticky = False
End Sub
public static Rect GetElementRect(FrameworkElement element)
{
GeneralTransform buttonTransform = element.TransformToVisual(null);
Point point = buttonTransform.TransformPoint(new Point());
return new Rect(point, new Size(element.ActualWidth, element.ActualHeight));
}
Public Shared Function GetElementRect(element As FrameworkElement) As Rect
Dim buttonTransform As GeneralTransform = element.TransformToVisual(Nothing)
Dim point As Point = buttonTransform.TransformPoint(New Point())
Return New Rect(point, New Size(element.ActualWidth, element.ActualHeight))
End Function
上記のコードでは、実際にセカンダリ・タイルが作成/削除できたかどうかの結果を使って、コマンド・ボタンの表示を再設定している。また、ユーザーに問い合わせるポップアップが出ている間にアプリ・バーが閉じてしまわないように、アプリ・バーのIsStickyプロパティをコントロールしている。
●現在のページが「ピン留め」されているかどうかを調べるには?
TileIdを使って調べればよい。
現在のページをこれから「ピン留め」するとしたらどんなTileIdになるかは算出できるはずだ。それと同じTileIdを持ったセカンダリ・タイルがすでに存在するかどうかは、次のコードで調べることができる。
private bool IsPinned(string tileId)
{
return Windows.UI.StartScreen.SecondaryTile.Exists(tileId);
}
Private Shared Function IsPinned(tileId As String) As Boolean
Return Windows.UI.StartScreen.SecondaryTile.Exists(tileId)
End Function
このメソッドは、前述した「画面表示時にコマンド・ボタンの表示を設定するコード」で使っている。
●セカンダリ・タイルからの起動時に特定の処理を行うには?
起動時に、セカンダリ・タイル作成時に設定したTileIdとArgumentsが渡されるので、それに応じた処理を記述すればよい。
セカンダリ・タイルから起動された場合、AppクラスのOnLaunchedメソッドに渡されるLaunchActivatedEventArgs型の引数「args」のプロパティに、セカンダリ・タイルの情報が入っている(次の2つ)。
セカンダリ・タイルから起動された場合は、これら2つともに有効な文字列が入ってくる。既定のタイルから起動されたときには、Argumentsがnull(VBではNothing)になっているので区別ができる(TileIdには既定値があって、nullにならない)。
参考までに、起動時に受け取ったargs.TileIdとargs.Argumentsを画面に表示させてみると、次の画像のようになる。
●まとめ
セカンダリ・タイルを作成/削除するコードはそれほど難しくない。ユーザーの許可を受けずに作成/削除できない点には注意が必要かもしれない。また、本稿では触れなかったが、セカンダリ・タイルもライブ・タイルにできる。
難しいのは、TileIdの生成の仕方やArgumentsに設定する文字列の決め方だ。この2つだけで起動時の画面遷移と遷移先での処理をコントロールしなければならないのだから、十分な設計が必要になるだろう。
詳しくは、次のドキュメントを参考にしてほしい。
Copyright© Digital Advantage Corp. All Rights Reserved.