c# - Xamarin Forms - 有序列表和 ArgumentOutOfRange

标签 c# xaml xamarin xamarin.forms

我已经与这个异常(以及随后的严重崩溃)斗争了大约一天了。我在 Xamarin Forms 中有一个 ListView 可以对标题进行分组。就我从调用堆栈中收集到的信息而言,错误是由于分组而发生的。我通过从 ListView 中删除分组来验证这一点,应用程序显示数据而不会崩溃。几周前我什至对代码进行了比较,但没有什么特别之处。 这也仅在新启动时发生,后续启动不会引发此异常或崩溃。

我还能如何进一步调试和解决这个问题?

Exception stack trace

ListView 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; }
}

绑定(bind)属性和 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没有处理 Reset由 ReplaceRange 生成。

作为短期解决方法,您可以通过不使用 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;

在我看来,崩溃似乎是由尝试重新渲染模板引起的,因为绑定(bind)上下文已更改......所以也许这个 hack 也适用于 Android......

您在上面的示例代码中同时设置了 GroupDisplayBindingGroupHeaderTemplate ...我假设是因为您正在试验...您应该只设置一组一次...使用 GroupDisplayBinding 也可以避免我预期的问题。

关于c# - Xamarin Forms - 有序列表和 ArgumentOutOfRange,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45476237/

相关文章:

c# - 无法在 MVVM 中完成模式中介

xamarin - 4.7 的新功能 - 寻找一种在 C# 中指定 RowDefinitions ="1*, Auto, 25, 14, 20"的方法

android - Xamarin Media 插件不适用于 Android

c# - .rdlc 文件中的排序问题

C# 将两个类的数据合并到其中一个类中

wpf - 在 Xaml 中将 TreeView 与 ContextMenu 绑定(bind)

android - Xamarin Forms MasterDetail 页面导航导致 Android 崩溃 [致命信号 6 (SIGABRT),代码 -6],适用于 iOS 和 UWP

c# - 定位到文件夹并执行应用程序 C#

c# - 如何创建c# exe?

c# - 不使用 XAML 进行绑定(bind) [WPF]