WPF DataGrid复制行后TextBox绑定源联动异常问题
问题原因
你当前的复制逻辑存在两个问题,直接导致重复行绑定联动:
- 插入集合时直接传入了原
TransactionItem对象的引用,集合中两个条目指向内存中同一个对象实例,双向绑定修改任意一个条目对应对象的属性,自然会同步反映到所有指向该实例的行上。 - 代码直接修改了原对象的
ID属性,会覆盖被复制行原本的ID值,属于逻辑错误。
修复方案
核心逻辑是插入新行前必须创建独立的TransactionItem实例,将原对象的属性值拷贝到新实例后,再把新实例插入集合,禁止直接插入原对象引用。
方案1:手动属性拷贝(最稳妥,推荐属性较少时使用)
直接修正后台点击事件代码即可:
private void DuplicateItem_Click(object sender, RoutedEventArgs e){ TransactionItem originalItem = ((FrameworkElement)sender).DataContext as TransactionItem; if (originalItem == null) return; // 创建独立的新对象实例 TransactionItem newItem = new TransactionItem { // 给新对象分配独立ID,不要修改原对象的ID ID = transactionViewModel.TransactionDataGridItems.Count + 1, // 逐行拷贝原对象的所有业务属性值 Amount = originalItem.Amount, // 按照你的TransactionItem定义,补充其他需要复制的属性,例如: // Remark = originalItem.Remark, // TransactionTime = originalItem.TransactionTime, // Category = originalItem.Category }; int insertIndex = transactionViewModel.TransactionDataGridItems.IndexOf(originalItem) + 1; transactionViewModel.TransactionDataGridItems.Insert(insertIndex, newItem); }
方案2:对象克隆(适合属性较多的场景)
如果TransactionItem属性较多,手动赋值过于繁琐,可以给实体类增加克隆方法:
public class TransactionItem { public int ID { get; set; } public decimal Amount { get; set; } // 其他属性定义... /// <summary> /// 创建当前对象的副本 /// </summary> public TransactionItem Clone() { // 仅包含值类型属性时,MemberwiseClone即可满足需求 TransactionItem clonedItem = (TransactionItem)this.MemberwiseClone(); // 如果类中包含引用类型属性(比如自定义类、集合等),需要在这里单独为引用类型属性创建新实例,避免嵌套引用共用 // 例如:clonedItem.Tags = new List<Tag>(this.Tags); return clonedItem; } }
对应点击事件可以简化为:
private void DuplicateItem_Click(object sender, RoutedEventArgs e){ TransactionItem originalItem = ((FrameworkElement)sender).DataContext as TransactionItem; if (originalItem == null) return; TransactionItem newItem = originalItem.Clone(); newItem.ID = transactionViewModel.TransactionDataGridItems.Count + 1; int insertIndex = transactionViewModel.TransactionDataGridItems.IndexOf(originalItem) + 1; transactionViewModel.TransactionDataGridItems.Insert(insertIndex, newItem); }
注意事项
- 如果实体包含引用类型成员,必须对引用类型成员也做独立拷贝(即深拷贝),否则嵌套属性依然会出现多行星级联动的问题。
- 所有针对新行的属性修改(比如分配新ID),都要作用在新创建的副本对象上,不要改动原对象的属性值。
内容的提问来源于stack exchange,提问作者Polar
相关产品推荐
相关产品推荐

