Xamarin使用RecycleElement表单Listview CachingStrategy未正确更新绑定上下文

时间:2017-02-08 10:49:20

标签: android listview xamarin.forms mvvm-light

我目前正在努力解决工作中的问题,我们有一个带有RecycleElement策略的ListView,但这会导致ViewCells出现意外行为。

当我点击ViewCell时,发生的第一件事是调用OnBindingContextChanged事件,这发生在OnTapped事件被调用之前。按下ViewCell后,应用程序会导航到另一个视图,用户可以在其中更改相应的数据。当用户导航回上一页时,应该发生的是输入的新数据应该显示在ViewCell中但是这不会发生,即使通过我能够获得CollectionChanged,OnBindingContextChanged事件也不会被触发来自ObservableCollection对象的事件,该对象与ListView的ItemsSource绑定。

当我删除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中,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来更改项目;会按预期在ObservableCollection中引发CollectionChanged事件,但当RecycleElement策略处于活动状态时,它不会传播到ViewCell。

我能够让这个工作的唯一方法是通过这个糟糕的方法,

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

但是,这显然会导致UI'故障',快速删除项目然后重新添加它。

这可能是ListView中的错误还是还有其他事情发生?

1 个答案:

答案 0 :(得分:0)

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

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