【发布时间】:2017-06-25 22:45:27
【问题描述】:
我目前在工作中遇到一个问题,我们有一个使用 RecycleElement 策略的 ListView,但这会导致 ViewCells 出现意外行为。
当我点击 ViewCell 时,首先发生的是调用 OnBindingContextChanged 事件,这发生在调用 OnTapped 事件之前。按下 ViewCell 后,应用导航到不同的视图,用户可以在其中更改其相应的数据。当用户导航回上一页时,应该发生的是输入的新数据应该显示在 ViewCell 中,但这不会发生,即使我能够获得 CollectionChanged,也不会触发 OnBindingContextChanged 事件来自绑定到 ListView 的 ItemsSource 的 ObservableCollection 对象的事件。
当我删除 CachingStrategy 时,我从 ListView ViewCells 中获得了预期的行为,当用户按下 ViewCell 时没有任何反应,但是当用户返回原始页面时,调用 OnBindingContextChanged 事件并正确更新数据。
我们需要应用程序性能的回收策略,因为 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 中,DisplayItem 是这样暴露的
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; 即可更改项目确实按预期在 ObservableCollection 中引发了 CollectionChanged 事件,但是当 RecycleElement 策略处于活动状态时,这不会传播到 ViewCell。
我能够让它工作的唯一方法是通过这种糟糕的方法,
DisplayItems.RemoveAt(lastSelectedItem);
await Task.Delay(50);//Horrible 'fix'
DisplayItems.Insert(lastSelectedItem, touchformItem);
但这显然会通过快速删除一个项目然后重新添加它而导致 UI“故障”。
这可能是 ListView 中的错误还是发生了其他事情?
【问题讨论】:
-
不确定您的期望,但如果我没记错的话,列表视图中的元素只有在它们自己实现 INotifyPropertyChanged 事件时才会更新它们的数据......所以这是完成了吗?如果是这样,您需要在列表视图中显示的元素中加载新数据
-
对象有一个 ObservableObject 基类,它实现了 INotifyPropertyChanged 接口,我发现了这个问题并将其作为这个线程的答案
标签: android listview xamarin.forms mvvm-light