0

I have a ListView (native) with dynamic content and I want to know how to detect when the user scrolls it, but not the style of "isScrolling = true/false", instead I want to know when the user scrolls it up, and when the user scrolls it down.

I tried this trick: https://stackoverflow.com/a/27294644/4668642 But the problem is that it's only return "true/false" (actually it's fires a Sub) and it floods the Sub too (I mean, I scroll the ListView very hard and the Sub is being fired multiple times, so the action it's being bugged).

I don't know if there is a Native way (Like an event as ManipulationDelta [it's doesn't works]) or another trick like that post.

This is my code for now:

'On a shared file'
Public Shared Function GetScrollViewer(depObj As DependencyObject) As ScrollViewer
    If TypeOf depObj Is ScrollViewer Then
        Return TryCast(depObj, ScrollViewer)
    End If

    For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(depObj) - 1
        Dim child = VisualTreeHelper.GetChild(depObj, i)

        Dim result = GetScrollViewer(child)
        If result IsNot Nothing Then
            Return result
        End If
    Next
    Return Nothing
End Function

'on OnNavigatedTo event'
AddHandler GetScrollViewer(LVNot).ViewChanged, AddressOf LVNot_ViewChanged

'At the end of the Main.xaml.vb file'
Private Sub LVNot_ViewChanged()
    If Cab.isUp = True Then
        Cab.goDownSub()
    End If
End Sub

Note1: "Cab" is a "Custom AppBar control" (UserControl), isUp is a boolean that return True when Cab is up (visible), and False when it's down (Hide), and goDownSub() is a Sub that Hide the "Cab"

Note2: This code is made with VB (VisualBasic), but I work with C# too. I don't have any problem with answerd made with C# instead of VB.

Community
  • 1
  • 1
JuanP. Zuniga
  • 65
  • 3
  • 13

2 Answers2

0

Hmm, cause listview itself contains a built in scroll viewer you can not put this control in another scroll viewer and get the scroll offset easily, my suggestion is to use a stack panel in a ScrollViwer and monitor the changes in event of ViewChanged of scrollViwer and get the currently offset by VerticalOffset() method.

HesamM
  • 36
  • 3
0

Okey, I found a way to get the listview's position.

The follow code was extracted from https://stackoverflow.com/a/4954586/4668642

var scrollViewer = FindScrollViewer(listBox);
var offset = scrollViewer.VerticalOffset;

static ScrollViewer FindScrollViewer(DependencyObject parent)
{
    var childCount = VisualTreeHelper.GetChildrenCount(parent);
    for (var i = 0; i < childCount; i++)
    {
        var elt = VisualTreeHelper.GetChild(parent, i);
        if (elt is ScrollViewer) return (ScrollViewer)elt;
        var result = FindScrollViewer(elt);
        if (result != null) return result;
    }
    return null;
}

Then it's possible to determinate which direction was the listview scrolling to:

Double offSetNew, offSetOld

private void LVNot_ViewChanged()
{
    dynamic ScrollViewer = FindScrollViewer(LVNot);
    offSetNew = ScrollViewer.VerticalOffset;

    if (offSetOld != 0) { //To avoid (offSetOld > offSetNew) being fired in the first instance
        if (offSetOld > offSetNew) {
            //Go Up
        } else if (offSetOld < offSetNew) {
            //Go Down
        }
    }

    offSetOld = offSetNew;
}
Community
  • 1
  • 1
JuanP. Zuniga
  • 65
  • 3
  • 13