You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MAUI分组ListView多分组时删除子项触发Java.Lang.IllegalStateException异常

MAUI分组ListView多分组时删除子项触发Java.Lang.IllegalStateException异常

看起来你遇到的是MAUI ListView在Android平台多分组场景下的典型视图绑定异常,这个问题的根源主要是Android原生ListView的视图复用机制和MAUI集合更新通知的交互冲突——多分组时,直接嵌套遍历集合并删除的操作会导致视图无法正确从父容器解绑,进而触发这个异常。下面给你几个可行的解决方案:

解决方案1:优化删除逻辑,避免遍历枚举器时修改集合

你当前的嵌套foreach遍历方式,在删除子项时可能会让枚举器处于无效状态,使得ListView的分组适配器无法正确同步视图状态。可以改成先定位目标分组再执行删除,同时显式确保操作在UI线程执行(虽然RelayCommand默认在UI线程,显式调用会更稳妥):

修改你的ButtonOk命令:

[RelayCommand]
private async Task ButtonOk(DetailData data)
{
    // 确保集合修改操作在UI线程执行
    await MainThread.InvokeOnMainThreadAsync(() =>
    {
        // 快速定位包含目标子项的分组
        var targetGroup = GroupData.FirstOrDefault(group => group.Contains(data));
        
        if (targetGroup != null)
        {
            // 从分组中删除目标子项
            targetGroup.Remove(data);
        }
    });
}

这种写法不仅更简洁高效,还避免了遍历枚举器时修改集合的潜在风险,能让ListView的适配器正确接收集合变更通知,完成视图更新。

解决方案2:替换为CollectionView(推荐)

MAUI中的ListView是从Xamarin.Forms继承的旧控件,在分组、动态集合更新等场景下,官方更推荐使用CollectionView——它针对MAUI的跨平台渲染做了大量优化,能从根源上避免这类Android视图绑定异常,同时支持更多现代布局特性。

步骤1:修改XAML布局为CollectionView

把原来的ListView替换为CollectionView,配置分组模板:

<RefreshView Command="{Binding RefreshCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
    <ScrollView>
        <Grid>
            <CollectionView ItemsSource="{Binding GroupData}" 
                            IsGrouped="True">
                <!-- 分组头部模板 -->
                <CollectionView.GroupHeaderTemplate>
                    <DataTemplate x:DataType="daten:GroupData">
                        <Label Text="{Binding Name}" 
                               Padding="10,5" 
                               BackgroundColor="LightGray"/>
                    </DataTemplate>
                </CollectionView.GroupHeaderTemplate>
                <!-- 子项模板 -->
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="daten:DetailData">
                        <Grid Padding="10" ColumnDefinitions="*,Auto">
                            <Label Text="{Binding Detail}" 
                                   VerticalOptions="Center"/>
                            <ImageButton Source="ok.jfif"
                                        Command="{Binding Source={RelativeSource AncestorType={x:Type local:MainPageViewModel}}, Path=ButtonOkCommand}" 
                                        CommandParameter="{Binding .}"
                                        Grid.Column="1"/>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </Grid>
    </ScrollView>
</RefreshView>

步骤2:复用或优化删除逻辑

CollectionView对集合变更的处理更健壮,无论用你原来的删除逻辑还是优化后的版本,都能避免Android平台的视图绑定异常,整体交互体验也会更流畅。

为什么单分组场景正常?

当只有一个分组时,ListView的视图复用机制没有被充分触发,删除子项后视图能快速完成解绑和更新;但多分组时,原生ListView会复用更多视图容器,此时如果集合更新的通知不规范,就会出现视图被多个父容器引用的异常。

备注:内容来源于stack exchange,提问作者PatrickBremen

火山引擎 最新活动