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

WinForm中ListView从CSV添加自定义列按文件名左连接填充值

实现方案

你当前的CSV加载逻辑硬编码了两列存储,无法适配多列场景,按以下步骤调整即可实现左连接填充列的需求。

1. 定义通用CSV存储字段

在窗体类级别添加以下字段,替换原有分散的listA、listB存储结构:

// 存储CSV表头列名
private readonly List<string> _csvHeaders = new List<string>();
// 存储CSV映射数据:键为文件名(忽略大小写适配Windows文件命名规则),值为<列名,列值>键值对
private readonly Dictionary<string, Dictionary<string, string>> _csvFileMap = 
    new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

2. 改造CSV加载方法

替换原有的LoadCSV方法,支持任意列数的CSV读取,自动识别表头,加载完成后一次性给ListView添加额外列:

private void LoadCSV()
{
    _csvHeaders.Clear();
    _csvFileMap.Clear();
    using (var reader = new StreamReader(@"C:\test.csv"))
    {
        // 读取第一行作为表头
        string headerLine = reader.ReadLine();
        if (string.IsNullOrWhiteSpace(headerLine)) return;
        string[] headers = headerLine.Split(',');
        _csvHeaders.AddRange(headers);

        // 逐行读取数据内容
        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();
            if (string.IsNullOrWhiteSpace(line)) continue;
            string[] values = line.Split(',');
            
            // 第一列为文件名,作为关联匹配键
            string fileName = values[0];
            var rowData = new Dictionary<string, string>();
            for (int i = 0; i < headers.Length; i++)
            {
                // 行数据列数不足时补空值,避免索引越界
                rowData[headers[i]] = i < values.Length ? values[i] : string.Empty;
            }
            _csvFileMap[fileName] = rowData;
        }
    }

    // 额外列仅需添加一次,跳过CSV第一列(Name列已作为ListView首列存在)
    for (int i = 1; i < _csvHeaders.Count; i++)
    {
        listView1.Columns.Add(_csvHeaders[i], 120); // 列宽可根据实际需求调整
    }
}

注意:LoadCSV方法仅需在窗体构造函数或Form_Load事件中调用一次即可,不要放在树节点点击事件里重复调用,避免重复添加列。

3. 补全文件遍历的列填充逻辑

原代码中用固定长度数组存储子项的写法不适合动态列场景,调整为动态集合后,在你标注// CODE HERE的位置添加循环填充逻辑即可,修改后的文件遍历代码如下:

foreach (FileInfo file in nodeDirInfo.GetFiles())
{
    item = new ListViewItem(file.Name, 1);

    // 先查找当前文件在CSV中是否有匹配记录
    _csvFileMap.TryGetValue(file.Name, out var matchRow);

    var subItems = new List<ListViewItem.ListViewSubItem>
    { 
        new ListViewItem.ListViewSubItem(item, "File"),
        new ListViewItem.ListViewSubItem(item, file.LastAccessTime.ToShortDateString())
    };

    // 遍历CSV所有非关联列,匹配到值就填充,没匹配到留空
    for (int i = 1; i < _csvHeaders.Count; i++)
    {
        string colValue = string.Empty;
        if (matchRow != null)
        {
            matchRow.TryGetValue(_csvHeaders[i], out colValue);
        }
        subItems.Add(new ListViewItem.ListViewSubItem(item, colValue ?? string.Empty));
    }

    item.SubItems.AddRange(subItems.ToArray());
    listView1.Items.Add(item);
}

补充说明

  • 如果你的CSV存在带逗号的字段(比如用双引号包裹的文本内容),直接用Split(',')会出现解析错误,这种场景建议引入CsvHelper这类成熟的CSV解析库处理,不需要自己写拆分逻辑。
  • 上述代码默认使用忽略大小写的文件名匹配,符合Windows文件系统的命名规则,如果需要严格区分大小写,修改字典初始化时的字符串比较器即可。
  • 如果需要支持CSV文件修改后热更新,重新加载CSV前记得先把ListView中之前添加的额外列移除,避免列重复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:03:21