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

.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字符串存储,读取时反序列化:

  1. 安装System.Text.Json或Newtonsoft.Json NuGet包
  2. 修改模型类:
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);
        }
    }
}
  1. 更新数据库:可卸载应用清除旧数据库,或在ListService.Init中先调用await db.DropTableAsync<Liste>();再重新创建表(注意:会丢失原有数据)。

方案3:使用One-to-Many关系

创建独立的Item模型类,建立Liste与Item的一对多关系:

  1. 创建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; }
    }
}
  1. 修改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>();
    }
}
  1. 更新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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:12:09