Обновление инструментария WP7 Удалено GetItemsInView () из LongListSelector - PullRequest
6 голосов
/ 19 августа 2011

С последним обновлением Windows Phone Toolkit они переработали внутреннюю часть LongListSelector для выпуска Mango.Одним из изменений было удаление поддержки функции GetItemsInView() (теперь она возвращает пустой список).Ранее эта функция возвращала список элементов, которые в данный момент были видны на экране.Я использовал это, чтобы получить ссылку на самый верхний видимый элемент при переходе от страницы, чтобы я мог поддержать восстановление после захоронения с помощью ScrollTo(object item).

Кто-нибудь знает, какой будет предложенная альтернатива?Я знаю, что с надгробием Манго гораздо меньше проблем, но я все же хотел бы поддержать его, и могут быть некоторые другие сценарии, в которых я хотел бы вспомнить положение прокрутки.В моем списке в некоторых случаях тысячи предметов.

Ответы [ 3 ]

4 голосов
/ 24 августа 2011

Из того, что я могу сказать по новым битам, вы должны подписаться на события Link и Unlink LLS.Link передаст аргумент, содержащий элемент, добавленный в видимую часть LLS.Unlink делает то же самое для тех элементов, которые удалены из LLS.Таким образом, вы должны сделать что-то вроде этого:

List<string> trackedItems = new List<string>();

private void myListOfStrings_Link(object sender, LinkUnlinkEventArgs e)
{
    var x = e.ContentPresenter;
    if (x == null || x.Content == null)
        return;
    trackedItems.Add(x.Content.ToString());
}

private void myListOfString_Unlink(object sender, LinkUnlinkEventArgs e)
{
    var x = e.ContentPresenter;
    if (x == null || x.Content == null)
        return;
    trackedItems.Remove(x.Content.ToString());
}

Обратите внимание, что Link и Unlink будут запускаться для КАЖДОГО визуализированного элемента в базовом списке, поэтому, если вы используете функции группировки LLSтогда вам придется расширить свой тест на то, отслеживать или нет элемент, основываясь на том, какой тип действительно возвращается.Поэтому, если у вас есть какой-то групповой объект, для которого вы хотите отслеживать базовые объекты, вы можете сделать что-то вроде этого:

private void myGroupedListOfObjects_Link(object sender, LinkUnlinkEventArgs e)
{
    var x = e.ContentPresenter;
    if (x == null || x.Content == null)
        return;
    var myObject = x.Content as MyObject;
    if (myObject != null)
    {
        foreach (var item in myObject.Items)
        {
            trackedItems.Add(item);
        }
    }
}

Надеюсь, это поможет!Дайте нам знать, если это сработает.

3 голосов
/ 19 января 2012

LongListSelector использует ScrollViewer внутри (очевидно, начиная с выпуска августа 2011 г.).Этот факт можно использовать для восстановления позиции списка после надгробия, следуя примеру, приведенному для http://damianblog.com/2011/01/21/wp7-scroll-pivot/ для основного контроллера.

В OnNavigatedFrom() запомните смещение прокрутки:

    private bool _newPageInstance = true;
    private double _scollOffset = double.NaN;

    protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedFrom(e);

        var scrollViewer = FindScrollViewer(LongList);
        State["scrollViewer.VerticalOffset"] = scrollViewer.VerticalOffset;
        State["PreservingPageState"] = true;
        _newPageInstance = false;
    }

    private static ScrollViewer FindScrollViewer(DependencyObject parent)
    {
        var childCount = VisualTreeHelper.GetChildrenCount(parent);
        for (var i = 0; i < childCount; i++)
        {
            var elt = VisualTreeHelper.GetChild(parent, i);
            if (elt is ScrollViewer) return (ScrollViewer)elt;
            var result = FindScrollViewer(elt);
            if (result != null) return result;
        }
        return null;
    }

И восстановите его в OnNavigatedTo(), если приложение было захоронено:

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        if (!_newPageInstance || !State.ContainsKey("PreservingPageState"))
        {
            return;
        }

        _scollOffset = (double)State["scrollViewer.VerticalOffset"];
    }

    private void LongList_Loaded(object sender, RoutedEventArgs e)
    {
        if (double.IsNaN(_scollOffset)) return;

        var longListSelector = (LongListSelector)sender;
        var scrollViewer = FindScrollViewer(longListSelector);
        scrollViewer.ScrollToVerticalOffset(_scollOffset);
        _scollOffset = double.NaN;
    }
2 голосов
/ 02 марта 2012

Подход Link / Unlink вообще не работает для восстановления позиции прокрутки. Даже если вы настраиваете коллекцию, вы не знаете, прокручиваете ли вы вверх или вниз, и размер коллекции будет варьироваться в зависимости от свойства BufferSize LongListSelector.

Решение FindScrollViewer в ответе Квакуло, однако, работает.

Если кому-то нужна VB.Net-версия этого кода:

Friend Function FindScrollViewer(parent As DependencyObject) As ScrollViewer

    Dim childCount = VisualTreeHelper.GetChildrenCount(parent)

    For i As Int32 = 0 To childCount - 1

        Dim elt = VisualTreeHelper.GetChild(parent, i)

        If elt.GetType Is GetType(ScrollViewer) Then Return CType(elt, ScrollViewer)

        Dim result = FindScrollViewer(elt)
        If result IsNot Nothing Then Return result

    Next

    Return Nothing

End Function
...