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

*ScrollViewer を巡るまとめ[#u7ab4e56]
サンプルプロジェクト [[ScrollViewer_Tips.zip>https://skydrive.live.com/redir.aspx?cid=793b87c06d2f0cd5&resid=793B87C06D2F0CD5!1899&parid=793B87C06D2F0CD5!223]]

大きな画像など画面に入りきらないエレメントをスクロールして表示したい時に使用するのが ScrollViewer です。ScrollViewer の中に Image コントロールを配置するだけで、Image サイズが ScrollViewer のサイズを超えたとき、指で触ってスクロールさせることが出来ます。

便利ですね。Windows Mobile の頃は大変でした。

**ScrollViewer の各種プロパティ [#edb58f11]
ScrollViewer には表示しているエレメントの大きさやスクロール状態などのプロパティが用意されていて、どのような状態にあるか分かります。

たとえば ScrollableWidth == 0 であれば横にははみ出していない事が分かります。

右の画像は、

-Image コントロールが 450x500
-表示している画像が 2000x1500

です。
#ref(scrollviewer_tips-01.jpg,around,nolink,right,75%);

|Actual*|ScrollViewer が実際に画面に表示されているサイズ|
|Viewport*|ScrollViewer の中の表示可能領域|
|Extent*|ScrollViewer が表示しているエレメントのサイズ|
|Scrollable*|ScrollViewer が表示しているエレメントがはみ出しているサイズ|
|*Offset|ScrollViewer 左上からの縦横のスクロール位置|

Viewport が表示してるサイズ(=ScrollViewサイズ)、Extent が画像サイズ、Scrollable がはみ出しているサイズになっているのが分かると思います。

**スクロールさせないようにする [#f3515f03]
ScrollView.HorizontalScrollBarVisibility/VerticalScrollBarVisibility を Disable にすると、縦横のスクロールを出来ないようにすることが出来ます。
Expression Blend では、''HorizontalScrollBarVisibility がデフォルト Disable'' になっており水平方向のスクロールが無効になっているので注意が必要です。

**コードでスクロールさせる [#bb8f9d25]
ScrollViewer のスクロール位置を変更するには、ScrollViewer.ScrollToHorizontalOffset/ScrollToVerticalOffset メソッドで移動させるピクセル数を指定することで水平・垂直方向のスクロールを行えます。原点は左上が 0,0 です。

このときに *ScrollBarVisibility = Disable にっていると、ScrollTo* メソッドでスクロールをさせてもスクロールしないので注意が必要です。

以下が、オートスクロールのサンプルです。
本当なら Storyboard でアニメーションしたいところですが、スクロールがメソッドなので DispatcherTimer でスクロールしました。

 private void autoscroll_button_Click(object sender, System.EventArgs e)
 {
    DispatcherTimer timer = new DispatcherTimer();
    timer.Interval = TimeSpan.FromMilliseconds(10);
    timer.Tick += (s, args) =>
    {
        // スクロールする
        this.scrollViewer.ScrollToHorizontalOffset(this.scrollViewer.HorizontalOffset + 1);
        this.scrollViewer.ScrollToVerticalOffset(this.scrollViewer.VerticalOffset + 1);
        
        double ho = this.scrollViewer.HorizontalOffset;
        double vo = this.scrollViewer.VerticalOffset;
        double sw = this.scrollViewer.ScrollableWidth;
        double sh = this.scrollViewer.ScrollableHeight;
        
        // 右端か下に達したら停止
        if (ho >= sw || vo >= sh)
        {
            ((DispatcherTimer)s).Stop();
            MessageBox.Show("停止しました");
        }
    };
    timer.Start();
 }


**Transform で拡大表示してもスクロールしない [#wf201c62]
ScrollViewer 内のエレメントを Transform.ScaleY 等で拡大表示しても、ScrollViewer でスクロールさせることは出来ません。というのも Translform.ScaleY 等で拡大表示しているのは ''コントロールのサイズはそのままで拡大表示している'' だけなので、実際のコントロールサイズは変わっていません。
ScrollViewer は格納しているエレメントサイズを基準にスクロールするので、拡大表示しただけではスクロールさせることは出来ません。

**端っこのイベントを取得する [#l03c4c07]
ScrollViewer で一番下や右下で、ぐぐっと引っ張って手を離すとびよよーんと画像が元の位置に戻ります。
この状態をイベントとして取得するには、XAML で VisualState を定義すれば可能です。

以下では ListBox 内の ScrollViewer のイベントを取得しています。

WP7.5 でリストボックスのスクロールエンドで圧縮されるときのイベントを取る
http://blogs.msdn.com/b/shintak/archive/2011/08/06/10193347.aspx