You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:02:14