Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get the VerticalOffset of a LongListSelector in WP8

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.

like image 719
gjulianm Avatar asked Feb 27 '13 19:02

gjulianm


1 Answers

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;
}
like image 193
pantaloons Avatar answered Sep 22 '22 15:09

pantaloons