#setlinebreak(on);
[[WP TIPS に戻る>wp7/tips]]

*パノラマを横スライドアニメーションする [#y4fbbffe]
サンプルプロジェクト [[Panorama_slide.zip>https://skydrive.live.com/redir.aspx?cid=793b87c06d2f0cd5&resid=793B87C06D2F0CD5!1909&parid=793B87C06D2F0CD5!223]]

#htmlinsert(u2b,id=47DYtkpAD4s,width=480,height=360;)

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

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

**PanningLayer を取得する [#mbd6ab2f]
画面上に配置した 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 をスクロールする [#s1a95406]
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);
 }

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

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

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

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

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