c# – Xamarin表单 – 有序列表和ArgumentOutOfRange

我已经和这个例外(以及随后的硬崩溃)争夺了大约一天.我在Xamarin Forms中有一个ListView,可以对标题进行分组.尽管我可以从调用堆栈中收集,但由于分组,错误正在发生.我通过从ListView中删除分组来验证这一点,并且应用程序显示数据而不会崩溃.我甚至将代码差异化了几周,并没有什么突出的.这也仅在新的启动时发生,后续启动不会抛出此异常或崩溃.

我还有什么可以进一步调试和解决这个问题?

《c# – Xamarin表单 – 有序列表和ArgumentOutOfRange》

列表视图XAML

<ListView x:Name="ListViewItems"
            ItemsSource="{Binding ItemsGrouped}"
            GroupDisplayBinding="{Binding Key.DisplayText}"
            IsGroupingEnabled="true">
    <ListView.GroupHeaderTemplate>
        <DataTemplate>
            <ViewCell>
                <cells:MyGroupHeaderView/>
            </ViewCell>
        </DataTemplate>
    </ListView.GroupHeaderTemplate>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <cells:ItemCellView />
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

MyGroupHeaderView XAML

<StackLayout VerticalOptions="Center">
    <Label Text="{Binding Key.DisplayText}">
    </Label>
</StackLayout>

分组C#代码

var result = from s in myItems
    orderby s.ItemDateTime
    group s by s.GetSortGroupInfo()
    into itemGroup
    select new Grouping<GroupInfo, ItemViewModel>(itemGroup.Key, itemGroup);

GroupInfo类(用于排序和显示)

public class GroupInfo
{
    public string DisplayText { get; set; }

    public int SortValue { get; set; }
}

绑定属性和Setter

public ObservableRangeCollection<Grouping<GroupInfo, ItemViewModel>> ItemsGrouped { get; }
    = new ObservableRangeCollection<Grouping<GroupInfo, StopViewModel>>();

this.ItemsGrouped.ReplaceRange(
    this.MyItems.GroupByDate()
        .OrderBy(f => f.Key.SortValue)
        .ToList());

最佳答案 根本问题是
TemplatedItemsList没有很好地处理ReplaceRange生成的
Reset.

作为短期解决方法,您可以通过不使用ReplaceRange来避免崩溃:

ItemsGrouped.Clear();
foreach (var item in MyItems.GroupByDate().OrderBy(f => f.Key.SortValue))
{
    ItemsGrouped.Add(item);
}

或者将caching strategy设置为回收:

<ListView x:Name="ListViewItems"
        ItemsSource="{Binding ItemsGrouped}"
        IsGroupingEnabled="true"
        CachingStrategy="RecycleElement">

有趣的是,如果你按照调用链来到UnhookItem,它有这样的评论:

//Hack: the cell could still be visible on iOS because the cells are reloaded after this unhook 
//this causes some visual updates caused by a null datacontext and default values like IsVisible
if (Device.RuntimePlatform == Device.iOS && CachingStrategy == ListViewCachingStrategy.RetainElement)
    await Task.Delay(100);
item.BindingContext = null;

对我的崩溃看起来是由于尝试重新渲染模板,因为绑定上下文已经改变…所以也许这个hack也适用于Android …

您正在上面的示例代码中设置GroupDisplayBinding和GroupHeaderTemplate …我假设您正在尝试…您应该一次只有一个…使用GroupDisplayBinding也可以避免我期望的问题.

点赞