Восстановить положение прокрутки в LongListSelector после надгробия - PullRequest
5 голосов
/ 13 июня 2011

Я пытаюсь работать с элементом управления LongListSelector из WP7 Silverlight Toolkit.Это заняло немного работы, но у меня наконец-то появилась работа с моим приложением.К сожалению, у меня возникают некоторые проблемы с правильной обработкой процесса захоронения.

Когда надгробия приложения (или пользователь переходит на другую страницу, выбирая элемент в списке), я сохраняю копию самого верхнего видимого элемента всписок.Я сохраняю его как в переменной класса, так и в коллекции состояний приложения.

ICollection<object> visibleItems = myLongList.GetItemsInView();
_lastItem = null;
if (visibleItems.Count > 0)
    _lastItem = visibleItems.First();
IDictionary<string, object> state = 
              Microsoft.Phone.Shell.PhoneApplicationService.Current.State;
state["IndexByName_LastTopItem"] = _lastItem;

Затем, когда пользователь возвращается на страницу, я проверяю одно из двух значений (состояние или переменную) и использую его длявосстановить последнюю позицию прокрутки.

if (_lastItem == null) 
{ 
    if (state.ContainsKey("IndexByName_LastTopItem")) 
    { 
        _lastItem = state["IndexByName_LastTopItem"] as Chemical; 
    } 
} 

if (_lastItem != null) 
    Dispatcher.BeginInvoke(() => { myLongList.ScrollTo(_lastItem); }); 

Это прекрасно работает, если только не надгробия приложения.В этом случае я не получаю никаких ошибок, но список полностью пуст, пока я не коснусь его и не перетяну.Как только я это сделаю, он снова отображается вверху списка.Я посмотрел на источник для элемента управления и обнаружил, что при вызове .ScrollTo (объект) он не получает совпадения.Дальнейшее исследование показало, что при поиске элемента для прокрутки сравнивается использование == вместо Equals.Я только переопределил Equals, и, по-видимому, по умолчанию == сравнивает (по замыслу) ссылки.При восстановлении элемента состояния после захоронения ссылки не совпадают.Я могу переопределить ==, но это неправильно.Я могу изменить и перестроить источник управления, чтобы вместо этого вызывать «равный» (я пытался, и это сработало), но он был написан людьми, намного умнее меня, и мне интересно, если я просто не понимаю.Есть ли лучший способ?

Ответы [ 2 ]

2 голосов
/ 01 августа 2011

Это исправление, которое я закончил ...

Поскольку исходный код находится в свободном доступе для инструментария, в итоге я отредактировал исходный код LongListSelector для вызова .Equals вместо ==. Похоже, что он работает правильно для моего варианта использования, и я подумал, что поделюсь, если кто-нибудь еще найдет это полезным ...

в LongListSelector.cs найдите функцию GetFlattenIndex (элемент объекта) и замените

if (item == _flattenedItems[index].Item)

с

if (item.Equals(_flattenedItems[index].Item))

, а затем в том же файле найдите функцию GetResolvedIndex (элемент объекта, из ContentPresenter contentPresenter) и замените

if (node.Value.Content == item)  // Nov 2010 Release
// OR
if (_flattenedItems[index].Item == item)  // Feb 2011 Release

с

if (item.Equals(node.Value.Content))  // Nov 2010 Release
// OR
if (item.Equals(_flattenedItems[index].Item))  // Feb 2011 Release

ОБРАТИТЕ ВНИМАНИЕ, что замена зависит от используемой вами загрузки инструментария!

После того, как вы внесли эти изменения в элемент управления, он будет правильно сопоставлять объекты, указанные в ScrollTo (объект), даже если ссылки не равны, если вы правильно переопределяете Equals для всех типов объектов, отображаемых в вашем LongListSelector. Не забывайте, что это относится как к вашему классу группировки, так и к классу элементов, если у вас есть сгруппированный список!

0 голосов
/ 15 июня 2011

Можете ли вы попробовать получить предмет в новом списке?

var _goodReference = myList.FirstOrDefault(x => x.id == _lastItem.Id);

if (_goodReference != null)     
Dispatcher.BeginInvoke(() => { myLongList.ScrollTo(_goodReference); }); 
...