酢ろぐ!

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

Windows PhoneでListBoxのスクロール状態が変更した時のイベントを拾う

ListBoxをグリグリ動かしている時にスクロール中か非スクロール中かを判定したい時があると思います。スクロール状態が変更した時のイベントを拾ってみましょう。

bool alreadyHookedScrollEvents = false;

VisualStateGroup FindVisualState(FrameworkElement element, string name) {
    if (element == null)
        return null;
    IList groups = VisualStateManager.GetVisualStateGroups(element);
    foreach (VisualStateGroup group in groups)
        if (group.Name == name)
            return group;
    return null;
}

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;
} 

/// <summary>
/// ビジュアルステートの変更イベントを定義する
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainListBox_Loaded(object sender, RoutedEventArgs e) {
    if (alreadyHookedScrollEvents) {
        return;
    }

    alreadyHookedScrollEvents = true;
    var viewer = FindSimpleVisualChild<ScrollViewer>(MainListBox);
    if (viewer == null) {
        return;
    }

    var element = VisualTreeHelper.GetChild(viewer, 0) as FrameworkElement;
    if (element == null) {
        return;
    }

    VisualStateGroup group = FindVisualState(element, "ScrollStates");
    if (group == null) {
        return;
    }

    group.CurrentStateChanging += (s, args) => {
        PageTitle.Text = args.NewState.Name;
    };
}