Определить, когда панель прокрутки списка WPF находится внизу?

Есть ли способ определить, прошла ли полоса прокрутки от ScrollViewer в ListView до нижней части виртуального пространства прокрутки? Я хотел бы обнаружить это, чтобы получить больше элементов с сервера, чтобы вставить в ObservableCollection в ListView.

Сейчас я делаю это:

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!");
    }

}

Это даже правильно? Мне также нужно различать вертикальную полосу прокрутки, вызывающую событие и горизонтальную полосу прокрутки, вызывающую его (т.е. Я не хочу продолжать генерировать вызовы на сервер, если вы прокручиваете горизонтально в нижней части окна).

Спасибо.

Ответ 1

Я понял это. Кажется, я должен был получать события из ScrollBar (<ListView ScrollBar.Scroll="currentTagNotContactsList_Scroll" в XAML), а не из зрителя. Это работает, но мне просто нужно понять способ избежать многократного вызова обработчика событий после того, как полоса прокрутки опущена. Может быть, таймер был бы хорош:

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!");

    }

}

Ответ 2

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

Ответ 3

Для UWP я получил это как

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

Ответ 4

Вы можете попробовать так:

 <ListView ScrollViewer.ScrollChanged="Scroll_ScrollChanged">

и в спине:

 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!");
    }