如何将子数组横向绑定到DataGridView控件
实现DataGridView横向显示Attributes集合的方案
1. 动态生成属性列
先遍历数据源中的所有HanAttribute对象,收集所有唯一的AttributeValue.Name作为列名,创建对应的DataGridViewTextBoxColumn:
// 假设你的数据源是BindingList<HanAttribute> hanDataList var attributeNames = hanDataList .SelectMany(h => h.Attributes) .Select(a => a.Name) .Distinct() .ToList(); foreach (var name in attributeNames) { var column = new DataGridViewTextBoxColumn { HeaderText = name, Name = $"col_{name}" }; dataGridView1.Columns.Add(column); }
2. 通过CellFormatting事件绑定属性值
在DataGridView的CellFormatting事件中,根据当前行的数据源和列名,动态匹配对应的AttributeValue并赋值:
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { if (e.RowIndex < 0 || e.ColumnIndex < 0) return; var column = dataGridView1.Columns[e.ColumnIndex]; if (column.Name == "col_HAN") return; // 跳过已绑定的HAN列 var attributeName = column.HeaderText; var hanItem = dataGridView1.Rows[e.RowIndex].DataBoundItem as HanAttribute; if (hanItem == null) return; var targetAttribute = hanItem.Attributes.FirstOrDefault(a => a.Name == attributeName); e.Value = targetAttribute?.Value ?? DBNull.Value; }
3. 处理属性集合的动态更新(可选)
因为Attributes是BindingList<AttributeValue>,可以在其ListChanged事件中触发DataGridView的行刷新,确保属性值变化时界面同步:
private void _content_ListChanged(object sender, ListChangedEventArgs e) { if (e.ListChangedType == ListChangedType.ItemChanged) { IsModified = true; // 找到当前项在DataGridView中的行并刷新 var row = dataGridView1.Rows.Cast<DataGridViewRow>() .FirstOrDefault(r => r.DataBoundItem == this); if (row != null) { dataGridView1.InvalidateRow(row.Index); } } OnPropertyChanged(nameof(Attributes)); }
4. 完整绑定示例
// 初始化数据源 var hanDataList = new BindingList<HanAttribute>(); hanDataList.Add(new HanAttribute { HAN = "123456789", Attributes = new BindingList<AttributeValue> { new AttributeValue { Name = "bool", Value = false }, new AttributeValue { Name = "int", Value = 123 }, new AttributeValue { Name = "string", Value = "empty string" } } }); // 添加HAN列 var hanColumn = new DataGridViewTextBoxColumn { HeaderText = "HAN", DataPropertyName = nameof(HanAttribute.HAN), Name = "col_HAN" }; dataGridView1.Columns.Add(hanColumn); // 生成属性列 var attributeNames = hanDataList .SelectMany(h => h.Attributes) .Select(a => a.Name) .Distinct() .ToList(); foreach (var name in attributeNames) { var column = new DataGridViewTextBoxColumn { HeaderText = name, Name = $"col_{name}" }; dataGridView1.Columns.Add(column); } // 绑定数据源和事件 dataGridView1.DataSource = hanDataList; dataGridView1.CellFormatting += dataGridView1_CellFormatting;
内容的提问来源于stack exchange,提问作者Anton Schrage
相关产品推荐
相关产品推荐

