酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows PhoneでListBoxのスクロールが一番下に来たかどうかをチェックする

いくつもListBoxへ表示するアイテムがある場合、全てをリストアップするわけにはいきません。

Windows Phone OS 7.1では、ScrollViewerのCompressionTopやCompressionBottomなどの圧縮関係のVisualStateに追加されていますので、そちらを利用することでiPhoneのようにスクロールバウンズを利用してページング処理をおこなうような事が可能です。⇒ListBoxでスクロールバウンズを利用して更新処理をおこなう

Windows Phone OS 7.0では、ListBoxのListVerticalOffsetの値を見て、一番下に来たかどうかをチェックを行い、例えばページング等の処理をおこなう方法が利用出来るのではないかと思います。

// ListBoxの要素のScrollViewerを取り出して格納する
ScrollViewer scrollViewer;

// ListVerticalOffsetの依存プロパティを定義
public readonly DependencyProperty ListVerticalOffsetProperty = DependencyProperty.Register("ListVerticalOffset", typeof(double), typeof(IllustIndexPage), new PropertyMetadata(new PropertyChangedCallback(OnListVerticalOffsetChanged)));

public double ListVerticalOffset {
    get { return (double)this.GetValue(ListVerticalOffsetProperty); }
    set { this.SetValue(ListVerticalOffsetProperty, value); }
}

VisualTreeから子要素を取得してくるメソッド。ListBoxからScrollViewer要素を取得するのに使用します。

T FindSimpleVisualChild<T>(DependencyObject element) where T : class {
    while (element != null) {
        if (element is T)
            return element as T;
        element = VisualTreeHelper.GetChild(element, 0);
    }
    return null;
}
private void MainListBox_Loaded(object sender, RoutedEventArgs e) {
    FrameworkElement element = (FrameworkElement)sender;
    element.Loaded -= MainListBox_Loaded;
    
    scrollViewer = FindSimpleVisualChild<ScrollViewer>(MainListBox);
    if (scrollViewer == null) {
        return;
    }
    
    Binding binding = new Binding();
    binding.Source = scrollViewer;
    binding.Path = new PropertyPath("VerticalOffset");
    binding.Mode = BindingMode.OneWay;
    this.SetBinding(ListVerticalOffsetProperty, binding);
}
    
private static void OnListVerticalOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
    IllustIndexPage page = obj as IllustIndexPage;
    if (page == null) {
        return;
    }
    ScrollViewer viewer = page.scrollViewer;
    
    // ListBoxが一番下まで来ているかチェックする
    if (viewer.VerticalOffset >= viewer.ScrollableHeight) {
        // 次のページを取得したりする
    }
}

参考