WinForms DataGrid无需重新绑定,向匿名类型数据源添加项
解决WinForms DataGrid绑定匿名类型列表后添加新项的问题
这个问题我之前也碰到过,匿名类型的内部特性确实给我们带来了不少限制,不过通过反射就能完美解决!你已经完成了最关键的两步——获取项类型和创建实例,剩下的就是通过反射操作原列表来添加新项了,具体步骤如下:
核心思路
匿名类型是编译器自动生成的internal类型,我们无法在代码中直接引用它的具体类型,但不管是什么类型的List<T>,都继承了通用的集合接口,而且我们可以通过反射调用它的Add方法来添加元素。
具体实现步骤
获取底层的列表数据源
DataGrid的数据源可能直接是List<匿名类型>,也可能是包装在BindingSource里,所以先把真实的列表取出来:var dataSource = yourDataGrid.DataSource; IList underlyingList = null; // 处理BindingSource的情况 if (dataSource is BindingSource bindingSource) { underlyingList = bindingSource.DataSource as IList; } else { underlyingList = dataSource as IList; } if (underlyingList == null) { throw new InvalidOperationException("数据源不是可修改的列表类型,请检查绑定的数据源"); }调用List的Add方法添加新项
利用反射获取列表的Add方法,然后传入你创建好的匿名类型实例:// 你已经实现的获取项类型和创建实例的代码 var itemType = ListBindingHelper.GetListItemType(underlyingList); var newItem = Activator.CreateInstance(itemType); // 若要给匿名类型属性赋值:因为匿名类型属性是只读的,需通过构造函数传入参数 // 示例:获取构造函数并传入对应属性值 // var constructor = itemType.GetConstructors().First(); // var newItem = constructor.Invoke(new object[] { 属性值1, 属性值2, ... }); // 调用Add方法添加新项 var addMethod = underlyingList.GetType().GetMethod("Add"); addMethod.Invoke(underlyingList, new[] { newItem });刷新DataGrid的绑定(如果用了BindingSource)
如果你的数据源是BindingSource,添加完项后需要手动刷新绑定,让DataGrid显示新数据:if (dataSource is BindingSource bs) { bs.ResetBindings(false); }
注意事项
- 匿名类型的属性是只读的,所以创建实例时如果需要设置属性值,必须通过构造函数传入对应参数,无法在创建后直接赋值修改。
- 确保绑定的原列表是可写的
List<T>,如果是只读集合(比如通过AsReadOnly()生成的),调用Add方法会抛出异常。
内容的提问来源于stack exchange,提问作者Tomasz
相关产品推荐
相关产品推荐

