Tina Debove Nigro

ListView/GridView - Detect a vertical scroll gesture

ListView/GridView - Detect a vertical scroll gesture

Les écrans de nos smartphones n’arrêtent pas de grandir, cela dit, il faut tout de même utiliser le peu d’espace disponible avec précaution. Dans une de mes applications, j’ai une page contenant une Grid et une ListView. La Grid contenant des informations complémentaires à ce qui est affiché dans la ListView. L’idée est de cacher ou réduire la taille de la Grid pour laisser plus de place à ListView. Pour cela, il me faut détecter lorsque l’utilisateur scrolle vers le bas ou vers le haut pour cacher ou afficher cette Grid.

Dans un premier temps, il faut récupérer le ScrollViewer de notre ListView/GridView, dans l’event Loaded (pour s’assurer que le composant est bien chargé).

public void OnLoaded(object sender, RoutedEventArgs routedEventArgs)

Avec le WinRTXamlToolkit (et son Helper que vous pouvez récupérer sur Internet), c’est très simple à faire.

var sV = (sender as ListView).GetFirstDescendantOfType();

Il s’agit ici de s’abonner à l’évènement ViewChanging qui comme son nom l’indique, est fired lorsque la scrollviewer voit sa vue évoluer. Rien de bien compliqué:

sV.ViewChanging += ScrollViewerOnViewChanging;

C’est dans ScrollViewerOnViewChanging que nous allons calculer si l’utilisateur va vers le haut ou vers le bas, avec une certaine sensibilité que vous pourrez modifier.

public static void ScrollViewerOnViewChanging(object sender, ScrollViewerViewChangingEventArgs scrollViewerViewChangingEventArgs)
{
    // Dans une variable on stock la nouvelle valeur de scroll vertical
    var voffset = scrollViewerViewChangingEventArgs.NextView.VerticalOffset;
    // si la scrollviewer est quasiment en haut ou en bas de la liste, on ne fait rien (pour eviter les effets de rebond par exemple)
    if (voffset < 50 || voffset > (_scrollWatchedSelector.scrollViewer.ScrollableHeight - 50))
    {
        return;
    }

    // si lascrollviewer a depasse de 30px l'ancienne valeur, on peut dire que l'utilisateur scroll vers le bas
    if (voffset > _scrollWatchedSelector.scroll + 30)
    {
        // Scrolling to bottom
        if (_scrollWatchedSelector.scrollingType != ScrollingType.ToBottom)
        {
            _scrollWatchedSelector.scrollingType = ScrollingType.ToBottom;
            ScrollingEventArgs e = new ScrollingEventArgs(_scrollWatchedSelector.scrollingType);
            _scrollWatchedSelector.InvokeScrollingEvent(e);
        }
    }
    // dans le cas contraire ...
    else if (voffset < _scrollWatchedSelector.scroll - 30)
    { // Scrolling to top
        if (_scrollWatchedSelector.scrollingType != ScrollingType.ToTop)
        {
            _scrollWatchedSelector.scrollingType = ScrollingType.ToTop;
            ScrollingEventArgs e = new ScrollingEventArgs(_scrollWatchedSelector.scrollingType);
            _scrollWatchedSelector.InvokeScrollingEvent(e);
        }
    }
    if (Math.Abs(_scrollWatchedSelector.scroll - voffset) > 30)
    {
        _scrollWatchedSelector.scroll = voffset;
    }
}

Je n’ai pas tout détaillé ici, mais j’ai opté personnellement pour un contrôle WinRT réutilisable à souhait dans mes/vos applications. Il est dispo sur GitHub: https://github.com/TinaNigro/ScrollWatchedSelector C’est en licence MIT, blablabla, libre a vous de me le piquer et en faire ce que vous voulez, et faire des pull requests sur ce repo.

Du coup, tout ce que vous avez à faire, c’est de changer votre ListView par

<scrollWatched:ScrollWatchedListView />
<scrollWatched:ScrollWatchedGridView />

Et de vous abonner a l’event GoingToTopOrBottom.

private void ListView_OnGoingTopOrBottom(IScrollWatchedSelector lv, EventArgs eventArgs)

Vous pourrez ensuite faire quelque chose du genre:

var e = eventArgs as ScrollingEventArgs;
if (e.ScrollingType == ScrollingType.ToBottom)
{
    Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => FadeOutHeader.Begin());
}
else if (e.ScrollingType == ScrollingType.ToTop)
{
    Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => FadeInHeader.Begin());
}

DEMO:

Tada! :)

ListView/GridView - Detect a vertical scroll gesture
Prev post

MSP Summit and Imagine Cup 2014

Next post

Disabling the Action Center gesture

ListView/GridView - Detect a vertical scroll gesture

Get in touch