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

C# WPF循环生成JSON时数据关联错误问题求助

问题解决:调整循环逻辑生成正确的保险-保单JSON结构

先确认类定义(确保结构匹配需求)

先确保你的Polis和PolisVerzekering类定义正确,示例如下:

public class Polis
{
    public string PolisNr { get; set; }
    public decimal Bedrag { get; set; }
}

public class PolisVerzekering
{
    public string VerzekeringNaam { get; set; }
    public List<Polis> PolisInfoList { get; set; } = new List<Polis>();
}

核心问题分析

你当前的循环逻辑没有隔离每个Canvas下的保单控件,要么复用了同一个全局保单列表对象,要么遍历了所有Canvas的保单控件,导致所有保单数据被重复添加到每个保险的关联列表中。

调整后的循环逻辑实现

下面是修改后的SaveVerzekeringPolis方法,核心思路是对每个Canvas单独处理,只收集当前Canvas内的保单数据:

private void SaveVerzekeringPolis()
{
    var verzekeringList = new List<PolisVerzekering>();

    // 逐个处理三个保险组Canvas
    verzekeringList.Add(ProcessSingleInsuranceGroup(FirstInsuranceGroup));
    verzekeringList.Add(ProcessSingleInsuranceGroup(SecondInsuranceGroup));
    verzekeringList.Add(ProcessSingleInsuranceGroup(ThirdInsuranceGroup));

    // 序列化为格式化后的JSON
    string json = JsonSerializer.Serialize(verzekeringList, new JsonSerializerOptions { WriteIndented = true });
    // 后续保存JSON的逻辑(如写入文件或发送接口)
}

// 提取复用方法,单独处理单个Canvas内的保险和保单数据
private PolisVerzekering ProcessSingleInsuranceGroup(Canvas targetCanvas)
{
    var currentVerzekering = new PolisVerzekering();

    // 获取当前Canvas内的保险名称(ComboBox选中值)
    var insuranceCombo = targetCanvas.Children.OfType<ComboBox>().FirstOrDefault();
    if (insuranceCombo != null)
    {
        currentVerzekering.VerzekeringNaam = insuranceCombo.SelectedItem?.ToString() ?? string.Empty;
    }

    // 获取当前Canvas内的所有保单控件组(假设每组用StackPanel包裹PolisNr和Bedrag的TextBox,且Tag标记为"PolisGroup")
    var polisContainers = targetCanvas.Children.OfType<StackPanel>()
                             .Where(panel => panel.Tag?.ToString() == "PolisGroup");

    foreach (var container in polisContainers)
    {
        // 从当前容器中获取对应的保单编号和金额输入框
        var polisNrBox = container.Children.OfType<TextBox>().FirstOrDefault(tb => tb.Name.Contains("PolisNr"));
        var bedragBox = container.Children.OfType<TextBox>().FirstOrDefault(tb => tb.Name.Contains("Bedrag"));

        // 验证输入并添加到当前保险的保单列表
        if (polisNrBox != null && decimal.TryParse(bedragBox?.Text, out decimal bedrag))
        {
            currentVerzekering.PolisInfoList.Add(new Polis
            {
                PolisNr = polisNrBox.Text.Trim(),
                Bedrag = bedrag
            });
        }
    }

    return currentVerzekering;
}

关键注意事项

  • 控件分组标识:确保每个保单的PolisNr和Bedrag输入框放在同一个容器(如StackPanel)中,并通过Tag或命名规则标记,保证只查找当前Canvas内的控件。
  • 独立列表实例:每个PolisVerzekering对象的PolisInfoList都是全新实例(类定义中已初始化),避免多个保险对象共享同一个列表。
  • 避免全局变量:不要在循环外部定义共享的保单列表,确保每个Canvas处理时生成专属的保单数据集合。

示例正确JSON结构

调整后生成的JSON会符合预期,每个保险仅关联自身的保单列表:

[
  {
    "VerzekeringNaam": "#1",
    "PolisInfoList": [
      {
        "PolisNr": "P001",
        "Bedrag": 250.50
      },
      {
        "PolisNr": "P002",
        "Bedrag": 400.00
      }
    ]
  },
  {
    "VerzekeringNaam": "#2",
    "PolisInfoList": [
      {
        "PolisNr": "P003",
        "Bedrag": 600.00
      }
    ]
  },
  {
    "VerzekeringNaam": "#3",
    "PolisInfoList": []
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 10:40:36