user5979
user5979

Reputation: 121

How to capture Scroll event in GridView in UWP

I have GridView with bound collection. I want to capture scroll change event when user scrolls GridView.

How to capture Scroll event in GridView in UWP?

Upvotes: 2

Views: 1384

Answers (1)

Decade Moon
Decade Moon

Reputation: 34286

You need access to the ScrollViewer in the GridView's template in order to add a listener to its ViewChanged event.

You should always have a helper method in your arsenal to search the visual tree for a control, something like:

public static class ViewHelper
{
    public static IEnumerable<DependencyObject> ChildrenBreadthFirst(this DependencyObject obj, bool includeSelf = false)
    {
        if (includeSelf)
        {
            yield return obj;
        }

        var queue = new Queue<DependencyObject>();
        queue.Enqueue(obj);

        while (queue.Count > 0)
        {
            obj = queue.Dequeue();
            var count = VisualTreeHelper.GetChildrenCount(obj);

            for (var i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(obj, i);
                yield return child;
                queue.Enqueue(child);
            }
        }
    }
}

Now you can access the ScrollViewer like this (simplified code):

<Page Loaded="onPageLoaded">
    <GridView x:Name="gridView"/>
</Page>
private void onPageLoaded(object sender, RoutedEventArgs e)
{
    var scrollViewer = gridView.ChildrenBreadthFirst().OfType<ScrollViewer>().First();
    scrollViewer.ViewChanged += onViewChanged;
}

private void onViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
    System.Diagnostics.Debug.WriteLine("Scrolled");
}

You must wait until the Loaded event for the ScrollViewer to be realized by the template (either Page.Loaded or the GridView.Loaded will do, I typically just use Page.Loaded for everything).

If you need to do this across multiple controls, you might want to bundle this into a reusable Behavior.

Upvotes: 2

Related Questions