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

MAUI中CollectionView绑定嵌套对象报错,求解决方案

解决方案

问题根源分析

  1. CollectionView分组配置错误:设置了IsGrouped="True"但未提供符合分组要求的数据结构,MAUI的分组CollectionView需要绑定到包含分组对象的集合,而非普通列表。
  2. Toto属性getter逻辑不合理:每次访问TestModel.Toto都会新建一个列表实例,既浪费资源也会导致绑定异常。
  3. 布局参数异常: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 18:40:20