C# WinForms中DataGridView绑定字符串数组数据不显示问题
C# WinForms DataGridView绑定数组属性不显示问题
问题场景
在C# WinForms项目中,DataGridView绑定短字段数据时运行正常,现需绑定包含长度为75的长字符串数组的数据源。
自定义LogList数据类包含6个带get/set访问器的独立属性,以及一个同样实现get/set访问器的字符串数组属性partlist。数据绑定完成后,6个独立属性(project、date_time、Qty、Pass、Fail、Result)可正常显示,但字符串数组partlist的内容无法在DataGridView中展示。调试时检查DataGridView的DataSource属性,确认数据源本身数据存储正常。
现有业务代码
Logview控件数据填充代码
public void populateLogData(string path) { StreamReader sr = null; BindingList<LogList> bindLogList; BindingSource bLogsource = new BindingSource(); List<LogList> loglist = new List<LogList>(); try { Logview.DataSource = null; Logview.Rows.Clear(); Logview.Columns.Clear(); Logview.AutoGenerateColumns = true; if (File.Exists(path)) { try { sr = new StreamReader(path); StringBuilder readline = new StringBuilder(sr.ReadLine()); if (readline.ToString() != null && readline.ToString() != "") { readline = new StringBuilder(sr.ReadLine()); while (readline.ToString() != null && readline.ToString() != "") { string[] subdata = readline.ToString().Split(','); LogList tloglist = new LogList(subdata[0], subdata[1], subdata[2], subdata[3], subdata[4], subdata[5], max_index); for (int i = 6; i < subdata.Length; i++) tloglist.setPartList(i-6, subdata[i]); loglist.Add(new LogList(subdata, subdata.Length)); readline = new StringBuilder(sr.ReadLine()); } } bindLogList = new BindingList<LogList>(loglist); bLogsource.DataSource = bindLogList; Logview.AutoGenerateColumns = true; Logview.DataSource = bindLogList; Logview.Columns[0].Width = 140; // project name Logview.Columns[1].Width = 140; // data/time Logview.Columns[2].Width = 90; Logview.Columns[3].Width = 90; Logview.Columns[4].Width = 90; Logview.Columns[5].Width = 90; // max_index is set from another part of code for(int i = 0; i <= max_index; i++) { int counter = 6 + i; Logview.Columns.Add(headertext[i], headertext[i]); Logview.Columns[counter].Width = 90; Logview.Columns[counter].HeaderText = headertext[i]; } } catch (IOException io) { MessageBox.Show("Error: Cannot Open log file."); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { if (sr != null) sr.Close(); } } else { MessageBox.Show("Log file not found \n" + path); } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { GC.Collect(); } }
LogList类定义代码
class LogList { const int max_size = 100; private string[] holdList; public string project { get; set; } public string date_time { get; set; } public string Qty { get; set; } public string Pass { get; set; } public string Fail { get; set; } public string Result { get; set; } public string[] partlist { get { return holdList; } set { holdList = value; } } public LogList(string project, string date_time, string Qty, string Pass, string Fail, string Result, int partsize) { this.project = project; this.date_time = date_time; this.Qty = Qty; this.Pass = Pass; this.Fail = Fail; this.Result = Result; partlist = new string[partsize+1]; } public void setPartList(int size, string getValue) { partlist[size] = getValue; } }
异常现象
project、date_time、Qty、Pass、Fail、Result6个固定字段列显示正常- 手动添加的
partlist对应列全部为空,无内容展示
问题根因
- 数据填充逻辑错误:循环中创建了
tloglist实例并填充了partlist数据,但最终加入集合的是通过new LogList(subdata, subdata.Length)创建的全新实例,该实例未填充任何partlist数据,且当前LogList类没有匹配该参数的构造函数,代码本身存在编译错误。 - 列绑定规则缺失:WinForms DataGridView默认的自动列生成逻辑只会识别类的一级标量属性,不会自动展开数组类型属性生成对应子列。手动添加的数组对应列没有设置
DataPropertyName绑定规则,控件无法定位要取数据源的哪个字段值,因此显示为空。 - 冗余列问题:开启
AutoGenerateColumns时,会为数组类型的partlist属性生成一个无效列,显示内容为System.String[],干扰正常展示。
修复方案
1. 修复数据填充逻辑
将读取每行数据时加入集合的对象替换为已经填充完数据的tloglist实例,删除无效的新实例创建代码:
// 原错误代码:loglist.Add(new LogList(subdata, subdata.Length)); // 替换为: loglist.Add(tloglist);
2. 关闭自动生成列,手动配置所有列的绑定规则
自动生成列无法处理数组属性的展开,直接关闭自动生成,手动为所有列指定绑定属性,数组元素的绑定语法为数组属性名[索引]:
// 绑定数据源前先关闭自动生成列 Logview.AutoGenerateColumns = false; // 先添加6个固定字段列,指定绑定属性 Logview.Columns.Add(new DataGridViewTextBoxColumn(){ DataPropertyName = "project", HeaderText = "项目名称", Width = 140 }); Logview.Columns.Add(new DataGridViewTextBoxColumn(){ DataPropertyName = "date_time", HeaderText = "记录时间", Width = 140 }); Logview.Columns.Add(new DataGridViewTextBoxColumn(){ DataPropertyName = "Qty", HeaderText = "总数量", Width = 90 }); Logview.Columns.Add(new DataGridViewTextBoxColumn(){ DataPropertyName = "Pass", HeaderText = "通过数量", Width = 90 }); Logview.Columns.Add(new DataGridViewTextBoxColumn(){ DataPropertyName = "Fail", HeaderText = "失败数量", Width = 90 }); Logview.Columns.Add(new DataGridViewTextBoxColumn(){ DataPropertyName = "Result", HeaderText = "测试结果", Width = 90 }); // 添加partlist数组对应列,逐列绑定数组指定索引的元素 for(int i = 0; i <= max_index; i++) { Logview.Columns.Add(new DataGridViewTextBoxColumn(){ DataPropertyName = $"partlist[{i}]", // 核心:绑定数组第i位的元素 HeaderText = headertext[i], Width = 90 }); } // 所有列配置完成后再绑定数据源 bindLogList = new BindingList<LogList>(loglist); Logview.DataSource = bindLogList;
3. (可选优化)修正数组初始化长度
LogList构造函数中数组初始化长度为partsize+1,如果max_index是数组最后一位的索引,数组长度设置为partsize即可,避免多余的空索引占用空间。
内容的提问来源于stack exchange,提问作者sujan_014
相关产品推荐
相关产品推荐

