使用WPF DataGrid拖拽功能报错:Cannot insert external objects to this list
解决DataGrid拖拽行报错“Cannot insert external objects to this list”
问题原因
这个报错通常由两种情况导致:
- 直接操作
DataGrid.ItemsSource转换的IList时,数据源实际是ICollectionView(包装后的视图),而非原始可修改集合; - 拖拽获取的
draggeditem不是数据源中的数据模型实例,而是UI元素(如DataGridRow),或是被集合判定为“外部对象”的实例。
修复代码示例
private static void ExchangeItems(object sender, object targetItem) { var dataGrid = sender as DataGrid; if (dataGrid == null) return; // 确保拖拽对象是数据源中的数据模型实例 // 若VisualHelper返回的是DataGridRow,需取其DataContext var draggedRow = VisualHelper.GetDraggedItem(dataGrid) as DataGridRow; var draggedItem = draggedRow?.DataContext; if (draggedItem == null) return; if (targetItem == null || ReferenceEquals(draggedItem, targetItem)) return; // 获取原始数据源集合,兼容ICollectionView场景 IList list = null; if (dataGrid.ItemsSource is ICollectionView collectionView) { list = collectionView.SourceCollection as IList; } else { list = dataGrid.ItemsSource as IList; } if (list == null) return; var targetIndex = list.IndexOf(targetItem); if (targetIndex == -1) return; // 移除并插入同一实例,避免被判定为外部对象 if (list.Remove(draggedItem)) { list.Insert(targetIndex, draggedItem); } }
关键修复点
- 获取正确数据源:如果
ItemsSource是ICollectionView,需通过SourceCollection拿到原始可修改集合; - 确认拖拽对象类型:确保拖拽的是数据模型实例,而非UI元素——若
VisualHelper.GetDraggedItem返回DataGridRow,需通过DataContext提取实际数据对象; - 验证集合操作:移除后插入同一实例,确保集合识别该对象为内部成员。
内容的提问来源于stack exchange,提问作者Syed Shayan Hasan
相关产品推荐
相关产品推荐

