How can I get the VerticalOffset of a LongListSelector in WP8
Asked Answered
H

1

6

In WP7, the LongListSelector had a underlying ScrollViewer, from which I could recover the vertical offset of the list. But in Windows Phone 8, there's no underlying ScrollViewer nor any similar class that provides me with that VerticalOffset property.

I've been searching and didn't find anything. I could settle with a function that gives the first visible element in the list, but I haven't found anything either. The ItemRealized event is not useful for that, as it doesn't give the exact item that is being shown on top of the viewport.

Hellfire answered 27/2, 2013 at 19:55 Comment(2)
shot in the dark - but I asked a similar question yesterday. Check out the answer. Maybe you could replace ScrollViewer with your LongListSelector? You wouldn't need to call ScrollToVerticalOffset() but you could possibly do somethign similar to get the offset? Just a thought! #15115491Feathercut
The problem is that I can't replace the LLS with an ScrollViewer, I need the ItemsSource binding and doing it by myself is not a good option. But thanks anyway.Hellfire
L
18

This will give you the first visible item in the LLS.

private Dictionary<object, ContentPresenter> items;

private object GetFirstVisibleItem(LongListSelector lls)
{
    var offset = FindViewport(lls).Viewport.Top;
    return items.Where(x => Canvas.GetTop(x.Value) + x.Value.ActualHeight > offset)
        .OrderBy(x => Canvas.GetTop(x.Value)).First().Key;
}

private void LLS_ItemRealized(object sender, ItemRealizationEventArgs e)
{
    if (e.ItemKind == LongListSelectorItemKind.Item)
    {
        object o = e.Container.DataContext;
        items[o] = e.Container;
    }
}

private void LLS_ItemUnrealized(object sender, ItemRealizationEventArgs e)
{
    if (e.ItemKind == LongListSelectorItemKind.Item)
    {
        object o = e.Container.DataContext;
        items.Remove(o);
    }
}

private static ViewportControl FindViewport(DependencyObject parent)
{
    var childCount = VisualTreeHelper.GetChildrenCount(parent);
    for (var i = 0; i < childCount; i++)
    {
        var elt = VisualTreeHelper.GetChild(parent, i);
        if (elt is ViewportControl) return (ViewportControl)elt;
        var result = FindViewport(elt);
        if (result != null) return result;
    }
    return null;
}
Ld answered 28/2, 2013 at 8:40 Comment(3)
Note that GetTemplateChild(“ViewPortControl”).Viewport.Top; will give you the VerticalOffset, but you can't scroll back to it so you will need to track the items.Ld
Works perfect and no noticeable performance overhead. Thanks!Hellfire
Hi pantaloons ,I need to get notified if the LLS reached end of the list, how can I do that? any clues?Zarla

© 2022 - 2024 — McMap. All rights reserved.