2013-02-27 1 views
6

В WP7 у LongListSelector был базовый ScrollViewer, из которого я мог восстановить вертикальное смещение списка. Но в Windows Phone 8 нет базового ScrollViewer или любого подобного класса, который предоставляет мне это свойство VerticalOffset.Как получить VerticalOffset для LongListSelector в WP8

Я искал и ничего не нашел. Я мог бы установить функцию, которая дает первый видимый элемент в списке, но я тоже ничего не нашел. Событие ItemRealized не подходит для этого, так как оно не дает точный элемент, который отображается поверх окна просмотра.

+0

снято в темноте, но вчера я задал аналогичный вопрос. Проверьте ответ. Может быть, вы можете заменить 'ScrollViewer' своим' LongListSelector'? Вам не нужно было бы вызывать 'ScrollToVerticalOffset()', но вы могли бы сделать что-то похожее, чтобы получить смещение? Просто мысль! http://stackoverflow.com/questions/15114991/how-to-use-scrollviewer-scrolltoverticaloffset – lhan

+0

Проблема в том, что я не могу заменить LLS на ScrollViewer, мне нужна привязка ItemsSource и сама это делать не является хороший вариант. Но все равно спасибо. – gjulianm

ответ

18

Это даст вам первый видимый элемент в 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; 
} 
+0

Кажется разумным. Я попробую это позже сегодня, спасибо! – gjulianm

+1

Обратите внимание, что 'GetTemplateChild (« ViewPortControl »). Viewport.Top;' даст вам VerticalOffset, но вы не сможете вернуться к нему, чтобы вам нужно было отслеживать элементы. – pantaloons

+0

Работает отлично и не заметно накладные расходы. Благодаря! – gjulianm