2017-02-08 13 views
0

В настоящее время я борюсь с проблемой на работе, у нас есть ListView с стратегией RecycleElement, но это вызывает неожиданное поведение в ViewCells.Xamarin Forms Listview с RecycleElement CachingStrategy не правильно обновляет контекст привязки

Когда я нажимаю на ViewCell, первое, что происходит, это то, что вызывается событие OnBindingContextChanged, это происходит до того, как вызвано событие OnTapped get. После нажатия ViewCell приложение переходит к другому представлению, в котором пользователь может изменить соответствующие данные. Когда пользователь переходит к предыдущей странице, должно произойти то, что новые данные, которые были введены, должны быть представлены в ViewCell, но этого не происходит, событие OnBindingContextChanged даже не запускается даже через я могу получить CollectionChanged событие из объекта ObservableCollection, который ограничен элементом ItemsSource ListView.

Когда я удаляю CachingStrategy, я получаю ожидаемое поведение из ListView ViewCells, когда пользователь нажал кнопку ViewCell, ничего не происходит, но когда пользователь возвращается к исходной странице, вызывается событие OnBindingContextChanged и данные должным образом обновляются.

Нам нужна Стратегия Recycle для производительности приложения, так как может случиться, что в ListView есть сотни элементов, и приложение должно оставаться полностью отзывчивым даже при прокрутке всех этих элементов.

Там не на много кода я могу поделиться, но вот то, что я могу поделиться

Часть XAML ListView определения

<ListView x:Name="TouchformList" 
    CachingStrategy="RecycleElement" 
    ItemsSource="{Binding DisplayItems}" 
    ItemTemplate="{StaticResource TouchformTemplateSelector}" 
    HasUnevenRows="True" 
    ItemSelected="Handle_ItemSelected" 
    SeparatorVisibility="None" /> 

DisplayItems является ObservableCollection
BaseTouchformItem расширяет класс ObservableObject

Внутри ViewModel DisplayItems отображаются так:

private ObservableCollection<BaseTouchformItem> _displayItems = new ObservableCollection<BaseTouchformItem>(); //This object is never re-assigned elsewhere 
    public ObservableCollection<BaseTouchformItem> DisplayItems 
    { 
     get 
     { 
      return _displayItems; 
     } 
    } 

Добавление элементов в DisplayItems не является проблемой, и они выглядят как ожидалось.

Изменение элемента путем простого вызова DisplayItems [lastSelectedItem] = touchformItem; действительно увеличивает событие CollectionChanged в ObservableCollection, как ожидалось, но когда активна стратегия RecycleElement, это не распространяется на ViewCell.

Единственный способ, которым я был в состоянии получить эту работу был через этот плохой метод,

DisplayItems.RemoveAt(lastSelectedItem); 
await Task.Delay(50);//Horrible 'fix' 
DisplayItems.Insert(lastSelectedItem, touchformItem); 

Но это, очевидно, вызывает UI «глюк» путем быстрого удаления элемента, а затем повторно добавить его.

Является ли это потенциально ошибкой в ​​ListView или что-то еще происходит?

+1

Не уверен, что вы ожидаете, но если я не ошибаюсь в элементе списка, они будут обновлять свои данные только в том случае, если они сами реализуют событие INotifyPropertyChanged ... так это делается? И если это так, вам нужно будет загрузить новые данные в элементе, который отображается в виде списка. – Depechie

+0

Объекты имеют базовый класс ObservableObject, который реализует интерфейс INotifyPropertyChanged, я нашел проблему и поставил ее как ответ на эта тема – zezioen

ответ

0

Я нашел проблему, по какой-то причине стратегия Recycle не нравится, когда я заменяю объект внутри ObservableCollection, он просто игнорирует происходящее и сохраняет список как есть.

Способ установки виртуальной машины состоял в том, что он каждый раз обновлял каждый элемент каждый раз, когда некоторые данные изменялись, а не просто обновлял сам элемент (таким образом, привязывание тоже не имело значения), я изменил его так, чтобы он обновлял элемент сам и не воссоздает тот же элемент снова, и теперь он работает как ожидалось.