.NET MAUI中添加集合属性setter后CollectionView不显示项
问题:添加setter后CollectionView不再显示列表项
之前项目运行正常,Android模拟器中CollectionView可正常显示所有列表项。但将数据模型类Liste的ItemListe属性从仅含getter改为添加setter后,CollectionView不再显示任何列表项。
修改前的Liste类
using SQLite; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Shopping_List.Models { public class Liste { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } public List<string> ItemListe { get; } = new List<string>(); } }
修改后的Liste类
using SQLite; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Shopping_List.Models { public class Liste { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } public List<string> ItemListe { get; set; } = new List<string>(); } }
原因分析
SQLite-net默认不支持直接存储List<string>这类集合类型:
- 当属性只有getter时,SQLite-net会忽略该属性(无法设置值),数据库表中不会创建对应列,模型实例化时
ItemListe通过默认的new List<string>()初始化,ViewModel能正常获取有效集合,CollectionView可正常渲染。 - 添加setter后,SQLite-net尝试将该属性映射到数据库列,但它无法直接序列化/反序列化
List<string>,导致从数据库读取Liste对象时,ItemListe被覆盖为null。MAUI绑定系统中,集合属性为null会导致数据模板无法正确渲染,最终CollectionView无内容显示。
解决方案
方案1:忽略集合属性(保持原有功能)
如果ItemListe不需要持久化到数据库,添加[Ignore]特性让SQLite-net跳过该属性映射:
using SQLite; using System.Collections.Generic; namespace Shopping_List.Models { public class Liste { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } [Ignore] public List<string> ItemListe { get; set; } = new List<string>(); } }
方案2:手动序列化集合为字符串存储
若需持久化ItemListe,可将集合序列化为JSON字符串存储,读取时反序列化:
- 安装
System.Text.Json或Newtonsoft.JsonNuGet包 - 修改模型类:
using SQLite; using System.Collections.Generic; using System.Text.Json; namespace Shopping_List.Models { public class Liste { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } // 数据库存储用的字符串字段 public string ItemListeJson { get; set; } // 业务逻辑用的集合属性,不映射数据库 [Ignore] public List<string> ItemListe { get => string.IsNullOrEmpty(ItemListeJson) ? new List<string>() : JsonSerializer.Deserialize<List<string>>(ItemListeJson); set => ItemListeJson = JsonSerializer.Serialize(value); } } }
- 更新数据库:可卸载应用清除旧数据库,或在
ListService.Init中先调用await db.DropTableAsync<Liste>();再重新创建表(注意:会丢失原有数据)。
方案3:使用One-to-Many关系
创建独立的Item模型类,建立Liste与Item的一对多关系:
- 创建
Item模型:
using SQLite; namespace Shopping_List.Models { public class Item { [PrimaryKey, AutoIncrement] public int Id { get; set; } public int ListeId { get; set; } // 外键关联Liste的Id public string Content { get; set; } } }
- 修改
Liste类:
using SQLite; using System.Collections.Generic; namespace Shopping_List.Models { public class Liste { [PrimaryKey, AutoIncrement] public int Id { get; set; } public string Name { get; set; } [Ignore] public List<Item> Items { get; set; } = new List<Item>(); } }
- 更新
ListService添加关联数据获取逻辑:
// 获取单个Liste及其关联的Items public static async Task<Liste> GetListeWithItems(int listeId) { await Init(); var liste = await db.Table<Liste>().FirstOrDefaultAsync(l => l.Id == listeId); if (liste != null) { liste.Items = await db.Table<Item>().Where(i => i.ListeId == listeId).ToListAsync(); } return liste; }
内容的提问来源于stack exchange,提问作者Jürgen Müller
相关产品推荐
相关产品推荐

