MAUI中CollectionView绑定嵌套对象报错,求解决方案
解决方案
问题根源分析
- CollectionView分组配置错误:设置了
IsGrouped="True"但未提供符合分组要求的数据结构,MAUI的分组CollectionView需要绑定到包含分组对象的集合,而非普通列表。 - Toto属性getter逻辑不合理:每次访问
TestModel.Toto都会新建一个列表实例,既浪费资源也会导致绑定异常。 - 布局参数异常:
VerticalStackLayout的Spacing="300000"超出合理范围,会引发布局渲染错误。
修复步骤及代码修改
1. 修正CollectionView配置与布局参数
如果不需要分组,直接移除IsGrouped="True";同时将Spacing调整为合理数值:
<CollectionView ItemsSource="{Binding TestModel.Toto}" EmptyView="pas de data"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="model:Toto"> <VerticalStackLayout Spacing="10"> <Label Text="{Binding Plop}"></Label> </VerticalStackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
2. 重构TestModel的Toto属性逻辑
在构造函数中一次性初始化列表,避免每次get都新建实例:
namespace testbinding.Model { public class TestModel : INotifyPropertyChanged { private string id; private string name; private List<Toto> toto; public string Id { get { return id; } set { id = value; OnPropertyChanged(nameof(Id)); } } public string Name { get { return name; } set { name = value; OnPropertyChanged(nameof(Name)); } } public List<Toto> Toto { get { return toto; } set { toto = value; OnPropertyChanged(nameof(Toto)); } } public event PropertyChangedEventHandler PropertyChanged; void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); public TestModel() { toto = getList(); } private List<Toto> getList() { List<Toto> totos = new List<Toto>(); totos.Add(new Toto { Id = 1, Plop = "plop" } ); totos.Add(new Toto { Id = 2, Plop = "plop2" } ); totos.Add(new Toto { Id = 3, Plop = "plop24" } ); totos.Add(new Toto { Id = 4, Plop = "plop241" } ); return totos; } } }
3. 简化ViewModel初始化逻辑
移除重复的TestModel初始化代码:
namespace testbinding.ViewModel { public class TestViewModel : INotifyPropertyChanged { public TestModel TestModel { get; } public TestViewModel() { TestModel = new TestModel(); } public event PropertyChangedEventHandler PropertyChanged; void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
额外优化建议
- 使用
ObservableCollection<T>替代List<T>,集合内容变化时UI会自动更新:private ObservableCollection<Toto> toto; public ObservableCollection<Toto> Toto { get { return toto; } set { toto = value; OnPropertyChanged(nameof(Toto)); } } // 构造函数中初始化 toto = new ObservableCollection<Toto>(getList()); - 引入CommunityToolkit.Mvvm库的
ObservableObject基类,简化INotifyPropertyChanged实现,无需手动编写OnPropertyChanged方法。
内容的提问来源于stack exchange,提问作者BarryF
相关产品推荐
相关产品推荐

