locked
How to detect top item in a list view

    Question

  • I'm trying to detect the top item in the users view as they scroll the ListView (XAML, C#).

    Currently I'm using the ContainerContentChanging event from this I can use the ContainerContentEventChangingArgs.Item to get a rough estimate of the top item.

    However I have two issues with this.

    • This event doesn't fire whenever the user scrolls, only when they scroll enough for the ListView to have to load new items coming into view.
    • The Item I get from the event args is always a few items to high as it is giving me the top item loaded, not the top item in view.

    So what would be a better way to go about this?


    Thursday, May 1, 2014 11:42 AM

Answers

  • Hi,

    You can follow up these steps below:

    1.Get the item container, in this case a GridViewItem, using the GridView's ItemContainerGenerator.

    2.Get the GridView's ScrollViewer. You can use FindVisualChild<T> methods:

    public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    return (T)child;
                }
    
                T childItem = FindVisualChild<T>(child);
                if (childItem != null) return childItem;
            }
        }
        return null;
    }

    3.Do MyGridViewItem.TransformToVisual(MyGridViewScrollViewer).TransformPoint(new Point(0, 0)); This will get you the top left corner of the item, relative to the entire scrollable panel (known as its Extent) of the ScrollViewer (this will be important later).

    You can refer to the link below to get more information:

    http://stackoverflow.com/questions/16705800/how-can-i-determine-which-items-in-a-gridview-that-are-visible-in-the-current-sc

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by BradStevenson Saturday, May 3, 2014 12:56 PM
    Friday, May 2, 2014 3:03 AM

All replies

  • I have also been looking at ScrollViewer's ViewChanged and ViewChanging methods. These look like they will fire at a more appropriate time.

    ScrollViewerViewChangingEventArgs also provides NextView.

    So this looks like it could be exactly what I need, however NextView is a ScrollViewerView. I don't see a way in which I could use this (probably the vertical offset) to identifiy the top ListViewItem?

    Thursday, May 1, 2014 12:39 PM
  • Hi,

    You can follow up these steps below:

      • Get the item container, in this case a GridViewItem, using the GridView's ItemContainerGenerator.
      • Get the GridView's ScrollViewer. You can use FindVisualChild<T> methods:
    public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    return (T)child;
                }
    
                T childItem = FindVisualChild<T>(child);
                if (childItem != null) return childItem;
            }
        }
        return null;
    }

     3.Do MyGridViewItem.TransformToVisual(MyGridViewScrollViewer).TransformPoint(new Point(0, 0)); This will get you the top left corner of the item, relative to the entire scrollable panel (known as its Extent) of the ScrollViewer (this will be important later).

    You can refer to the link below to get more information:

    http://stackoverflow.com/questions/16705800/how-can-i-determine-which-items-in-a-gridview-that-are-visible-in-the-current-sc

    Best Wishes!


  • We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

Friday, May 2, 2014 2:38 AM
  • Hi,

    You can follow up these steps below:

    1.Get the item container, in this case a GridViewItem, using the GridView's ItemContainerGenerator.

    2.Get the GridView's ScrollViewer. You can use FindVisualChild<T> methods:

    public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    return (T)child;
                }
    
                T childItem = FindVisualChild<T>(child);
                if (childItem != null) return childItem;
            }
        }
        return null;
    }

    3.Do MyGridViewItem.TransformToVisual(MyGridViewScrollViewer).TransformPoint(new Point(0, 0)); This will get you the top left corner of the item, relative to the entire scrollable panel (known as its Extent) of the ScrollViewer (this will be important later).

    You can refer to the link below to get more information:

    http://stackoverflow.com/questions/16705800/how-can-i-determine-which-items-in-a-gridview-that-are-visible-in-the-current-sc

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey. Thanks<br/> MSDN Community Support<br/> <br/> Please remember to &quot;Mark as Answer&quot; the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by BradStevenson Saturday, May 3, 2014 12:56 PM
    Friday, May 2, 2014 3:03 AM
  • Works perfectly, only thing I would mention is ItemContainerGenerator is depreciated in 8.1 so you can just use ItemControl.ContainerFromItem()
    Saturday, May 3, 2014 12:57 PM