パノラマを横スライドアニメーションする
サンプルプロジェクト 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 名前空間にあり自由に使用することが出来ますので、自作パノラマコントロールを作ることも出来るでしょう。