6
votes

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.

1
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! stackoverflow.com/questions/15114991/…lhan
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.gjulianm

1 Answers

18
votes

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