【问题标题】:Xamarin Forms Listview with RecycleElement CachingStrategy not properly updating binding contextXamarin Forms Listview 与 RecycleElement CachingStrategy 未正确更新绑定上下文
【发布时间】: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


【解决方案1】:

我发现了这个问题,由于某种原因,当我在 ObservableCollection 中换出一个对象时,回收策略不喜欢它,它只是忽略正在发生的事情并保持列表不变。

VM 的设置方式是,它会在每次某些数据更改时重新创建每个项目,而不是仅仅更新项目本身(从而使绑定也无关紧要),我对其进行了更改,以便它更新项目本身并且不会再次重新创建相同的项目,现在它可以按预期工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 2018-10-16
    • 2019-04-23
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多