You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7 MAUI更新ListView绑定的ObservableCollection时出现空引用异常

.NET 7 MAUI Android ListView 空引用异常问题分析与解决方案

问题现象

首次运行应用时数据加载正常,但点击按钮清空ObservableCollection再添加新数据时,Android端触发空引用异常,Windows端无此问题。切换ListViewCachingStrategy为RecycleElement后问题消失。

问题原因

这个情况大概率是**.NET 7 MAUI Android端ListView在默认RetainElement缓存策略下的已知BUG**:

  • 默认的RetainElement模式会保留每个Cell的实例,当清空集合再添加新数据时,旧Cell可能未正确解绑绑定关系,导致后续绑定新数据时出现空引用。
  • RecycleElement模式下Cell会被复用,系统会正确处理Cell的绑定生命周期,因此规避了该问题。

解决方案

方案1:使用RecycleElement缓存策略(推荐)

直接在ListView中指定缓存策略,这不仅能解决空引用问题,还能提升ListView的性能(尤其数据量大时):

<ListView ItemsSource="{Binding CurrentData}" CachingStrategy="RecycleElement">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ImageCell ImageSource="{Binding Description}"
                       Text="{Binding Name}"
                       Detail="{Binding Description}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

方案2:替换整个ObservableCollection实例

修改ViewModel实现INotifyPropertyChanged,更新数据时直接赋值新的ObservableCollection,触发ListView重新绑定:

修改SomeDataViewModel.cs:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace ListViewBugSample.ViewModels
{
    public class SomeDataViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<SomeData> _currentData;
        public ObservableCollection<SomeData> CurrentData
        {
            get => _currentData;
            set
            {
                if (_currentData != value)
                {
                    _currentData = value;
                    OnPropertyChanged();
                }
            }
        }

        public SomeDataViewModel()
        {
            CurrentData = new ObservableCollection<SomeData>() {
                new() { Description = "Desc1", Name = "Name1"}, 
                new() { Description = "Desc2", Name = "Name2" },
                new() { Description = "Desc3", Name = "Name3" } };
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class SomeData
    {
        public string Name { get; set; }
        public string Description { get; set; }
    }
}

修改MainPage.xaml.cs的更新方法:

private void UpdateListViewData(object sender, EventArgs e)
{
    var newData = new ObservableCollection<SomeData>
        {
            new() { Description = "NewData1", Name = "NewName1"},
            new() { Description = "NewData2", Name = "NewName2" },
            new() { Description = "NewData3", Name = "NewName3" } 
        }; 
    
    _listViewModelData.CurrentData = newData;
}

方案3:升级到更高版本的MAUI

该问题在.NET 8及后续版本的MAUI中已被修复,如果项目允许,升级到.NET 8+即可解决,无需修改现有代码逻辑。

结论

你的代码实现本身没有明显错误,这个空引用异常属于MAUI Android端在.NET 7版本的已知BUG。优先推荐使用RecycleElement缓存策略,既解决问题又提升性能;若需保留RetainElement模式,可选择替换集合实例或升级MAUI版本。

内容的提问来源于stack exchange,提问作者Ggilabert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:10:31