Windows タッチ&ジェスチャ研究室 Vol.03 ~Windows Phoneのタッチ#1~

今回から数回にわたり、Windows Phoneでのタッチとジェスチャーの話をします。
Windows Phoneだから何か特別ということはあまりなく、基本はSilverlightプラスアルファと考えれば良いので、SilverlightやWPFのアプリケーションに応用できるものもあります。
本文中でも、Windows向けのSilverlightやWPFを意識した説明を入れています。

2011年4月15日に、Windows Phone 7 アプリケーション開発 Deep Diveというセミナーを開催しました。
そのセミナーのタッチ&ジェスチャーのセッションをもとに説明します。
使用したスライドは、セミナーのWebサイトからダウンロードできます。


Windows PhoneでSilverlightを使用したアプリケーションを作成する場合、どのようにしてタッチやジェスチャーに対応させるかは、大きく上記の4つの方法があります。
まずScrollviewerを使用する方法で、これがいちばん簡単です。
次にマウスイベントを使用する方法があります。この方法は、Windows用のアプリを開発されたことがある方であれば、すぐに実装できます。
そして、マニピュレーションを使う方法があります。マニピュレーションとは、指がどれくらい動いたのかという情報を簡単に取得できる方法です。
マニピュレーションは、Windows版のSilverlightにはない機能で、Windows Phone用のSilverlightではサポートされます。WPFにもあります。
最後に、Touchクラスを使う方法があります。Touchクラスを使うと、指の動きを生のデータとして取得できます。

今回はこの中で、難易度0のScrollviewerコントロールを使用する方法を説明します。


上の図は、複数のボタンを縦に並べて貼り付けたアプリケーションです。
ボタンの数が少ないときは画面に全てのボタンが表示されますが、ボタンの数が増えてくると画面からはみ出してしまいます。
この例では、いちばん外側にGridがあり、その中にさらにGridが入っていて、その中にStackパネルが入っています。
そのStackパネルの中に、ボタンが並んでいます。
このようなアプリケーションを作成して実行しても、画面からはみ出した部分にあるボタンを表示させることはできません。
画面からはみ出していても、スクロールできないからです。

このような場合には、スクロールさせたいパネルをScrollviewerコントロールで囲みます。
以下の図は、StackパネルをScrollviewerで囲った例です。

Scrollviewerコントロールで囲うと、その部分をパン(指で画面上をなぞる)またはフリック(指で触り、はじくようにして移動させながら離す)でスクロールできるようになります。
Windows Phone用のアプリケーションを作る場合、表示させたいものが画面より大きくなる可能性があれば、それをScrollviewerで囲えばよいのです。
なお、Scrollviewerコントロールのすぐ内側には1つのコントロールしか含むことができないため、GridやStackなどのパネルをScrollviewerの中に用意し、そのパネルの中にコントロールを貼り付けることで複数のコントロールに対応させられます。

Windows用のSilverlightまたはWPFにもScrollviewerコントロールがあります。
Windows Phone用のScrollviewerは画面からはみ出しているときに、ジェスチャによって表示位置を変えることができます。Windows Phone用Silverlightが、そのような機能を持っているからです。
しかし、Windows用のSilverlightまたはWPFのScrollviewerコントロールを使用しても、ジェスチャには対応していません。
Windows用SilverlightまたはWPFのScrollviewerを使用してスクロールさせるには、指で動いた距離を計測し、その距離をもとにScrollviewerコントロールの表示位置を変えます。
以下のサンプルコードは、WPFでScrollviewerを使用し、その中の表示位置を変えるサンプルです。

void ScrollIconImage(double value)
{
    IconPanelOffset += value;

    if (IconPanelOffset < 0) // 左端を超えた場合
        IconPanelOffset = 0;
    else if (IconPanel.ActualWidth - iconPanelScroll.ActualWidth < IconPanelOffset) // 右端を超えた場合
        IconPanelOffset = IconPanel.ActualWidth - iconPanelScroll.ActualWidth;

    iconPanelScroll.ScrollToHorizontalOffset(IconPanelOffset);
}

Scrollviewerコントロールには、ScrollToHorizontalOffsetとScrollToVerticalOffsetというメソッドがあり、表示位置を引数として指定してメソッドを呼び出すことにより、表示位置を変えることができます。
サンプルでは、IconPanelOffsetフィールドという、Scrollviewerの表示位置を示すフィールドがあり、そこにどれだけ移動するかの情報を足す/引くことにより、表示位置を変えています。

マイクロソフト
田中達彦