パノラマを横スライドアニメーションする
サンプルプロジェクト Panorama_slide.zip
パノラマは Pivot と並んで横スクロールが出来るという WP7 を特徴づけているコントロールの一つです。
この Panorama コントロールは一つのコントロールになっていますが、内部的には3つのコントロールで構成されています。
- PanningBackroundLayer
- PanningLayer
- 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 名前空間にあり自由に使用することが出来ますので、自作パノラマコントロールを作ることも出来るでしょう。


