15

Is there a way to detect if the scrollbar from the ScrollViewer in a ListView has reached the bottom of the virtual scroll space? I would like to detect this to fetch more items from the server to put into the bound ObservableCollection on the ListView.

Right now I'm doing this:

private void currentTagNotContactsList_scrollChanged(object sender, ScrollChangedEventArgs e) {

    ListView v = (ListView)sender;


    if (e.VerticalOffset + e.ViewportHeight == e.ExtentHeight) {
        Debug.Print("At the bottom of the list!");
    }

}

Is this even correct? I also need to differentiate between the vertical scrollbar causing the event and the horizontal scrollbar causing it (i.e. I don't want to keep generating calls to the server if you scroll horizontally at the bottom of the box).

Thanks.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Max
  • 6,901
  • 7
  • 46
  • 61

5 Answers5

15
//A small change in the "Max's" answer to stop the repeatedly call.
//this line to stop the repeatedly call
ScrollViewer.CanContentScroll="False"

private void dtGrid_ScrollChanged(object sender, ScrollChangedEventArgs e)
                {
//this is for vertical check & will avoid the call at the load time (first time)
                    if (e.VerticalChange > 0)
                    {
                        if (e.VerticalOffset + e.ViewportHeight == e.ExtentHeight)
                        {
                            // Do your Stuff
                        }
                    }
                }
Narottam Goyal
  • 3,534
  • 27
  • 26
10

I figured it out. It seems I should have been getting events from the ScrollBar (<ListView ScrollBar.Scroll="currentTagNotContactsList_Scroll" in XAML) itself, rather than the viewer. This works, but I just have to figure a way to avoid the event handler being called repeatedly once the scrollbar is down. Maybe a timer would be good:

private void currentTagNotContactsList_Scroll(object sender, ScrollEventArgs e) {

    ScrollBar sb = e.OriginalSource as ScrollBar;

    if (sb.Orientation == Orientation.Horizontal)
        return;

    if (sb.Value == sb.Maximum) {
        Debug.Print("At the bottom of the list!");

    }

}
Dan J
  • 16,319
  • 7
  • 50
  • 82
Max
  • 6,901
  • 7
  • 46
  • 61
  • 4
    ScrollBar.Scroll doesn't exist for ListView in Windows 10 .. how to achieve this requirement in windows 10 – djkpA Jul 08 '15 at 11:48
4

For UWP I got it like this

<ScrollViewer Name="scroll" ViewChanged="scroll_ViewChanged">
    <ListView />
</ScrollViewer>

private void scroll_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
    var scrollViewer = (ScrollViewer)sender;
    if (scrollViewer.VerticalOffset == scrollViewer.ScrollableHeight)
            btnNewUpdates.Visibility = Visibility.Visible;
}
dnxit
  • 7,118
  • 2
  • 30
  • 34
  • 2
    Also works in WPF, using ScrollChanged="ScrollViewerScrollChangedEvent" ... +1 – BENN1TH Jul 29 '18 at 08:42
  • @dnxit exactly where do you put scrollviewer?? as i am having multiple Listviews on single UWP page, how can i relate particular scrollviewer with listview? – ace Aug 06 '18 at 07:05
3

you can try this way:

 <ListView ScrollViewer.ScrollChanged="Scroll_ScrollChanged">

and in Back:

 private void Scroll_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        // Get the border of the listview (first child of a listview)
        Decorator border = VisualTreeHelper.GetChild(sender as ListView, 0) as Decorator;
        // Get scrollviewer
        ScrollViewer scrollViewer = border.Child as ScrollViewer;
        if (scrollViewer.VerticalOffset == scrollViewer.ScrollableHeight)
        Debug.Print("At the bottom of the list!");
    }
radin
  • 251
  • 3
  • 16
2

Not recommand to use ScrollBar.Scroll , beacause if you scroll the middle wheel of the mouse, it won't work.

ScrollBar.Scroll="currentTagNotContactsList_Scroll"

The following support both right side scroll bar and mouse's wheel scroll.

in listbox's xmal:

                 ScrollViewer.ScrollChanged="ScrollViewer_ScrollChanged"

in c#:

        private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
            var listBox = (ListBox)sender;
            var scrollViewer =  (ScrollViewer)VisualTreeHelper.GetChild(listBox, 0);

            if (scrollViewer.VerticalOffset == scrollViewer.ScrollableHeight)
            {
                Console.WriteLine("____At the bottom of the list!");
            }
    }
Mike Yang
  • 2,581
  • 3
  • 24
  • 27