今回作っていく機能のスペックは、上述したシチュエーションの説明だけで十分だろう。それでは、さっそく実装していこう。まずは、3つのボタンを持ったアプリ・バーを、記事表示画面に追加する。
本アプリのソリューションをVS 2013で開き、ソリューション・エクスプローラで「ViewPage.xaml」ファイルをダブル・クリックして開く。そうしたら、次のコードを追加する。
……省略……
</Page.Resources>
<!-- 【第7回】アプリ・バーを追加 -->
<Page.BottomAppBar>
<CommandBar Background="#00a2e8">
<CommandBar.SecondaryCommands>
<AppBarButton Click="ShareButton_Click" Icon="Send" Label="シェアする"
ToolTipService.ToolTip="記事のURLを共有に送ります" />
<AppBarButton Click="CopyButton_Click" Icon="Copy" Label="URLをコピー"
ToolTipService.ToolTip="記事のURLをコピーします" />
<AppBarButton Click="BingsearchButton_Click" Icon="Find" Label="Bingで検索"
ToolTipService.ToolTip="記事のタイトルをBingで検索します" />
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
<!--
This grid acts as a root panel for the page that defines two rows:
* Row 0 contains the back button and page title
* Row 1 contains the rest of the page layout
-->
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
……省略……
アプリ・バーの実装方法は何通りかあるので、詳しくは「WinRT/Metro TIPS:アプリ・バーを簡単に実装するには?[Windows 8.1ストア・アプリ開発]」をご覧いただきたい。今回はCommandBarコントロールを使い、ボタンのアイコンにはシステムで用意されているSymbolIconクラスを使用した。なお、CommandBarコントロールはボタンを配置できる場所が左右2カ所にあって、CommandBar. PrimaryCommandsプロパティが右、CommandBar.SecondaryCommandsプロパティ(上のコードにある)が左だ。また、AppBarButtonコントロールのToolTipService.ToolTipプロパティに設定した文字列は、そのボタンのツールチップだ(マウスをボタン上で静止、または、タップしたまま長押しで表示される)。
なお、アプリ・バーはVS 2013のデザイン画面で表示されないことがある。次の画像のように、下のXAMLエディタで<CommandBar.SecondaryCommands>タグかその内側にカーソルを置けば表示される。
最後に、ボタンのClick属性の値(「ShareButton_Click」「CopyButton_Click」と「BingsearchButton_Click」)のところに順にカーソルを置いて[F12]キーを押して、それぞれのイベント・ハンドラのメソッドを自動生成しておく。
簡単な機能から実装していこう。まずは、プロトコル・アクティベーションを使って、ブラウザにBingの検索結果ページを表示させる。
Bingの検索ページを呼び出すhttpプロトコル(=URL)は、次のとおり。
http://www.bing.com/search?q={URLエンコードした検索文字列}
この文字列をUriオブジェクト(System名前空間)に変換し、Launcherクラス(Windows.System空間)のLaunchUriAsyncメソッドの引数に与える。すると、httpプロトコルに関連付けられているアプリ(デフォルトではIE)がシステムによって起動されるとともに、この文字列が渡されるのだ。
これは短い処理なので、コードビハインドに書いてしまおう。先ほど自動生成させたBingsearchButton_Clickメソッドに、次のコードを記述するだけで完成だ。
private async void BingsearchButton_Click(object sender, RoutedEventArgs e)
{
var item = this.DataContext as AtmarkItReader.DataModel.FeedItem;
string url = string.Format(
"http://www.bing.com/search?q={0}",
System.Net.WebUtility.UrlEncode(item.Title)
);
await Windows.System.Launcher.LaunchUriAsync(new Uri(url));
}
クリップボードとのデータのやりとりと、共有コントラクトでのやりとりは、どちらもDataPackageクラス(Windows.ApplicationModel.DataTransfer名前空間)を使う。まず、コピー機能から実装していこう。
プロジェクトのLogicフォルダに、新しくクラスを2つ作成する。まず1つ目は、DataPackageオブジェクトを扱うクラスだ。URLと記事タイトルをDataPackageオブジェクトにセットするメソッドを、SetUriAndTitleという名前の拡張メソッドとして作成しよう。DataPackageオブジェクトに対する拡張メソッドを収めるクラスなので「DataPackageExtension」という名前にする(次のコード)。
using System;
namespace AtmarkItReader.Logic
{
public static class DataPackageExtension
{
public static void SetUriAndTitle(
this Windows.ApplicationModel.DataTransfer.DataPackage package,
Uri pageUri, string pageTitle
)
{
// データのタイトル
package.Properties.Title = pageTitle;
// Webページへのリンクをセット
package.SetWebLink(pageUri);
// 汎用的なデータとするため、テキストとしてURLもセット
package.SetText(pageUri.ToString());
}
}
}
ここでセットするのは最初の2つ(Properties.TitleプロパティへのセットとSetWebLinkメソッドの呼び出し)だけでよさそうな気がするが、それでは「メモ帳」などにペースト操作をしても何もペーストされない。そのため、3つ目のSetTextメソッドの呼び出しも追加した。
次に、クリップボードの操作を担当するClipboardHandlerクラスを、同じくLogicフォルダに作成する。DataPackageオブジェクトを用意してクリップボードへ送るCopyUrlメソッドを次のコードのように記述する。
using System;
namespace AtmarkItReader.Logic
{
public static class ClipboardHandler
{
public static void CopyUrl(Uri pageUri, string pageTitle)
{
// コピー用のDataPackageオブジェクトを用意する
var package
= new Windows.ApplicationModel.DataTransfer.DataPackage()
{
RequestedOperation
= Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy,
};
// Webページのリンクとタイトルをセット(先ほど作った拡張メソッド)
package.SetUriAndTitle(pageUri, pageTitle);
// DataPackageオブジェクトをクリップボードへ送る
Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(package);
}
}
}
最後に、コードビハインドのCopyButton_Clickメソッドから上記のCopyUrlメソッドを呼び出せば、完成だ(次のコード)。
private void CopyButton_Click(object sender, RoutedEventArgs e)
{
AtmarkItReader.Logic.ClipboardHandler
.CopyUrl(this.webView1.Source, this.webView1.DocumentTitle);
// コピーが終わったらアプリ・バーを閉じる
// (何もしないと、処理が終わったことがユーザーに分からない)
this.BottomAppBar.IsOpen = false;
}
Copyright© Digital Advantage Corp. All Rights Reserved.