实现DataGridView转置绑定:按列绑定对象并支持动态列增删
实现DataGridView矩阵转置并支持动态列更新
我完全理解你想要的效果——把原本每行展示一个Emp对象的常规布局,转成每行对应Emp的一个属性(ID、Name、City),每列对应一个Emp实例的矩阵转置样式,而且还要在增删Emp对象时,DataGridView能自动同步添加或删除对应的列。下面是具体的实现方案:
步骤1:改用可动态通知的数据源
首先,把原来的Emp数组换成BindingList<Emp>,它自带CollectionChanged事件,能在集合增删元素时自动触发通知,这是实现动态更新的关键:
// 初始化可动态通知的Emp集合 var empList = new BindingList<Emp> { new Emp(1, "Devesh Omar", "Noida"), new Emp(2, "Roli", "Kanpur"), new Emp(3, "Roli Gupta", "Mainpuri"), new Emp(3, "Roli Gupta", "Kanpur"), new Emp(3, "Devesh Roli ", "Noida"), };
步骤2:初始化DataGridView的固定行
我们需要手动创建固定的3行(对应ID、Name、City),同时关闭自动列生成(避免默认的行式绑定干扰):
// 清空默认的列和行 dataGridView1.Columns.Clear(); dataGridView1.Rows.Clear(); // 关闭自动列生成 dataGridView1.AutoGenerateColumns = false; // 添加固定行:分别对应Emp的三个属性 dataGridView1.Rows.Add("ID"); dataGridView1.Rows.Add("Name"); dataGridView1.Rows.Add("City");
步骤3:编写同步逻辑实现转置展示
写一个方法,负责把BindingList<Emp>中的数据转置后填充到DataGridView中,处理列的增删和单元格值的更新:
private void SyncEmpToDataGridView(BindingList<Emp> empList) { // 先移除多余的列(当集合元素减少时) while (dataGridView1.Columns.Count > empList.Count) { dataGridView1.Columns.RemoveAt(dataGridView1.Columns.Count - 1); } // 遍历每个Emp对象,创建列并填充数据 for (int i = 0; i < empList.Count; i++) { var currentEmp = empList[i]; // 如果当前索引对应的列不存在,新建列(列名可以自定义) if (i >= dataGridView1.Columns.Count) { dataGridView1.Columns.Add($"EmpColumn_{i}", $"员工 {i+1}"); } // 把Emp的属性值填充到对应行的单元格中 dataGridView1.Rows[0].Cells[i].Value = currentEmp.ID; dataGridView1.Rows[1].Cells[i].Value = currentEmp.Name; dataGridView1.Rows[2].Cells[i].Value = currentEmp.City; } }
步骤4:绑定集合变更事件实现动态更新
给BindingList<Emp>绑定CollectionChanged事件,这样每当你添加或删除Emp对象时,DataGridView会自动同步更新:
// 绑定集合变更事件 empList.CollectionChanged += (sender, e) => { SyncEmpToDataGridView(empList); }; // 初始化时先同步一次数据 SyncEmpToDataGridView(empList);
额外优化:支持Emp属性值动态更新
如果需要在Emp对象的属性值修改时,DataGridView也能自动更新,可以让Emp类实现INotifyPropertyChanged接口:
public class Emp : INotifyPropertyChanged { private int _id; private string _name; private string _city; public int ID { get => _id; set { _id = value; OnPropertyChanged(nameof(ID)); } } public string Name { get => _name; set { _name = value; OnPropertyChanged(nameof(Name)); } } public string City { get => _city; set { _city = value; OnPropertyChanged(nameof(City)); } } public Emp(int id, string name, string city) { ID = id; Name = name; City = city; } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
之后你可以给每个单元格绑定对应的属性,或者在属性变更时重新触发同步,这样属性值修改时就能实时更新到DataGridView了。
内容的提问来源于stack exchange,提问作者CrApHeR
相关产品推荐
相关产品推荐

