第7回 ほかのアプリにデータを送る連載:Windowsストア・アプリ開発入門(2/4 ページ)

» 2013年11月29日 10時41分 公開
[山本康彦(http://www.bluewatersoft.jp/),BluewaterSoft]

画面にアプリ・バーを実装する

 今回作っていく機能のスペックは、上述したシチュエーションの説明だけで十分だろう。それでは、さっそく実装していこう。まずは、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}">
……省略……

アプリ・バーの実装(XAML)
「ViewPage.xaml」ファイルに太字の部分を追加する。
追加する場所は、最初のコントロール(ここではGridコントロール)の上だ。

 アプリ・バーの実装方法は何通りかあるので、詳しくは「WinRT/Metro TIPS:アプリ・バーを簡単に実装するには?[Windows 8.1ストア・アプリ開発]」をご覧いただきたい。今回はCommandBarコントロールを使い、ボタンのアイコンにはシステムで用意されているSymbolIconクラスを使用した。なお、CommandBarコントロールはボタンを配置できる場所が左右2カ所にあって、CommandBar. PrimaryCommandsプロパティが右、CommandBar.SecondaryCommandsプロパティ(上のコードにある)が左だ。また、AppBarButtonコントロールのToolTipService.ToolTipプロパティに設定した文字列は、そのボタンのツールチップだ(マウスをボタン上で静止、または、タップしたまま長押しで表示される)。

 なお、アプリ・バーはVS 2013のデザイン画面で表示されないことがある。次の画像のように、下のXAMLエディタで<CommandBar.SecondaryCommands>タグかその内側にカーソルを置けば表示される。

デザイン画面でアプリ・バーを見る デザイン画面でアプリ・バーを見る
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));
}

プロトコル・アクティベーションを実行するコード(C#)
太字の部分を入力する。
LaunchUriAsyncメソッドは非同期で実行されawaitキーワードを必要とするため、メソッドのシグネチャにはasyncキーワードが必要だ。
このページのデータ・コンテキストには1件の記事データを表すFeedItemオブジェクトがセットされているので、そのTitleプロパティで記事のタイトルが取得できる。それをWebUtilityクラス(System.Net名前空間)のUrlEncodeメソッドでURLエンコードして、URLを組み立てる。最後に、URL文字列からUriオブジェクトを生成して、LaunchUriAsyncメソッドを呼び出す。

コピー機能を実装する

 クリップボードとのデータのやりとりと、共有コントラクトでのやりとりは、どちらも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());
    }
  }
}

DataPackageExtensionクラス(C#)
SetUriAndTitle拡張メソッドは、引数としてDataPackageオブジェクトを受け取り、同じく引数として受け取った記事のURLとタイトルをそれにセットする。

 ここでセットするのは最初の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);
    }
  }
}

ClipboardHandlerクラス(C#)
CopyUrlメソッドは、DataPackageオブジェクトを生成し、先ほど作ったSetUriAndTitle拡張メソッドを呼び出して記事のURLとタイトルをセットし、最後にClipboardクラス(Windows.ApplicationModel.DataTransfer名前空間)のSetContentメソッドを使ってDataPackageオブジェクトをクリップボードへ送る。

 最後に、コードビハインドの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;
}

コピーを実行するコード(C#)
太字の部分を入力する。
CopyUrlメソッドに渡す引数(記事のUriオブジェクトとタイトル文字列)は、WebViewコントロールに実際に表示されているWebページのものとした。
また、コメントにもあるように、コードからアプリ・バーを閉じるようにしている。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。