WP TIPS に戻る

パノラマを横スライドアニメーションする

サンプルプロジェクト Panorama_slide.zip

パノラマは Pivot と並んで横スクロールが出来るという WP7 を特徴づけているコントロールの一つです。
この Panorama コントロールは一つのコントロールになっていますが、内部的には3つのコントロールで構成されています。

  1. PanningBackroundLayer
  2. PanningLayer
  3. PanningTitleLayer

Panorama コントロールをスライドさせると別々にスクロールする、タイトル部分、背景部分、コンテンツ部分は、これら3種類のクラスが別々に動作し制御しています。
これら3種類のクラスも動作内容自体はほぼ同一で、スクロールさせる対象が異なるだけ(おそらく)なので、ここでは PanningLayer を例に取り上げます。

PanningLayer を取得する

画面上に配置した Panorama をスライドさせるには、Panorama のインスタンスから既に存在している PanningLayer を取得します。

PanningLayer pl;

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
   // PanningLayer を取得する
   this.GetPanningLayer(this.Panorama);
}

private void GetPanningLayer(Panorama panorama)
{          
   // パノラマ配下の数を念のため確認。
   int count = VisualTreeHelper.GetChildrenCount(panorama);
   if (count > 0)
   {
       // 直下の Grid を取得
       Grid g = (Grid)VisualTreeHelper.GetChild(panorama, 0);

       // Grid 配下の PanningLayer を取得
       PanningLayer pl = (PanningLayer)VisualTreeHelper.GetChild(g, 2);

       // 格納しておく
       this.pl = pl;
   }
}

このように Loaded された後 ( VisualTree 構築完了後) に、VisualTreeHelper を使用して Panorama 内部のコントロールを取得しておきます。

PanningLayer をスクロールする

PanningLayer.GoTo メソッドで、Panorama を任意の X 位置にスクロールさせることが出来ます。

public void GoTo(int targetOffset, Duration duration, Action completionAction)

targetOffset に 100 、Duration に 1000ms を指定すると、画面左端から 100px の位置に 1秒間かけて移動します。completeAction に移動完了後に実行するメソッドを指定することが出来ます。
たとえば、

int count = 0;
int roundtrip = 3;
int leftOffset = -100;
int rightOffset = 100;

private void OK_Button_Click(object sender, System.EventArgs e)
{
   this.count = 0;
   this.leftOffset = -100;
   this.rightOffset = 100;
   this.Left();
}
 
public void Left()
{
   if (count > roundtrip)          
       return;         
   count++;

   this.pl.GoTo(this.leftOffset, new Duration(TimeSpan.FromMilliseconds(100)), this.Right);
}

public void Right()
{
   this.pl.GoTo(this.rightOffset, new Duration(TimeSpan.FromMilliseconds(100)), this.Left);
}

このコードを実行すると、パノラマ全体が左右にぶるぶるっと震えるアニメーションを行うことが出来ます。

折り返す

GoTo メソッドの targetOffset に 10000 など大きな値を指定すると、画面の遙か彼方に移動してしまいます。自動的に折り返ったスクロールはしません。
Panorama が開いた時「あのアニメーション」はどのようにしているのでしょうか?

PanningLayer.Wraparound メソッドと GoTo メソッドを組み合わせると、あのアニメーションを再現することが出来ます。

this.pl.Wraparound(1);
this.pl.GoTo(0, new Duration(TimeSpan.FromMilliseconds(800)), null);

まとめ

PanningLayer, PanningBackgroundLayer, PanningTitleLayer クラスは Micorosoft.Phone.Controls.Primitives 名前空間にあり自由に使用することが出来ますので、自作パノラマコントロールを作ることも出来るでしょう。