WPF自定义DataGrid如何在未知绑定集合类型时添加行?
问题描述
我正在创建一个继承自WPF DataGrid的自定义控件(CustomGrid),该控件使用时会将ItemsSource设置为ObservableCollection。我为其添加了剪贴板粘贴数据的功能,但当现有集合行数不足时,需要添加额外行,此时遇到了难题:由于CustomGrid会用于不同集合,无法直接引用集合的实体类。我尝试通过ItemsSource添加行,代码如下:
private void AddNewRow() { IList itemsSource = this.ItemsSource as IList; Type itemType = itemsSource.GetType().GenericTypeArguments[0]; object newRecord = Activator.CreateInstance(itemType); itemsSource.Add(newRecord); }
运行时出现错误:System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'
解决方案
错误根源:直接通过
itemsSource.GetType().GenericTypeArguments[0]获取泛型类型的方式不可靠。WPF绑定ItemsSource后,实际返回的可能是WPF内部包装的视图对象(如CollectionView),这类对象并非泛型集合,GenericTypeArguments数组为空,访问索引0自然触发越界异常。修复代码:
改用Items.SourceCollection获取原始数据源,同时通过Items.ItemType直接获取集合元素的类型,这是WPF提供的更可靠的方式:
private void AddNewRow() { // 获取原始的数据源集合 var sourceCollection = this.Items.SourceCollection as IList; if (sourceCollection == null) return; // 直接从Items属性获取元素类型,无需解析泛型 Type itemType = this.Items.ItemType; // 尝试实例化对象,检查是否存在有效无参构造函数 object newRecord = Activator.CreateInstance(itemType); if (newRecord == null) return; sourceCollection.Add(newRecord); }
- 额外提示:如果目标实体类没有无参构造函数,
Activator.CreateInstance会抛出异常。可以为自定义控件添加回调委托,允许外部传入实例化对象的逻辑,适配不同构造函数的实体类。
内容的提问来源于stack exchange,提问作者Grant McConville
相关产品推荐
相关产品推荐

