WPF C# MVVM场景下DataGrid更新前值变更问题
解决WPF MVVM中编辑文本框实时同步DataGrid的问题
问题根源
你当前的代码里,CurrentDocumentType = selectedDocumentType是直接的引用赋值,CurrentDocumentType和SelectedDocumentType指向同一个内存对象。所以修改TextBox绑定的CurrentDocumentType.DocumentTypeName时,本质是修改了DataGrid选中行对应的原对象属性,导致DataGrid实时更新。
解决方案核心
创建SelectedDocumentType的深拷贝副本作为CurrentDocumentType的编辑对象,编辑阶段仅修改副本;点击更新按钮时,再将副本的属性值同步到原对象,实现按需更新DataGrid。
具体实现步骤
1. 给DocumentType类添加深拷贝方法
如果DocumentType是简单类,手动复制属性最直接;若包含嵌套引用类型,需实现深拷贝:
public class DocumentType : INotifyPropertyChanged { public int IdDocumentType { get; set; } private string _documentTypeName; public string DocumentTypeName { get => _documentTypeName; set { _documentTypeName = value; OnPropertyChanged(nameof(DocumentTypeName)); } } // 深拷贝方法,根据实际属性扩展 public DocumentType Clone() { return new DocumentType { IdDocumentType = this.IdDocumentType, DocumentTypeName = this.DocumentTypeName // 其他属性逐一复制 }; } // INotifyPropertyChanged 实现 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 修改ViewModel中的属性赋值逻辑
把SelectedDocumentType的引用赋值改为拷贝赋值:
private DocumentType selectedDocumentType; public DocumentType SelectedDocumentType { get { return selectedDocumentType; } set { selectedDocumentType = value; // 赋值拷贝后的对象,而非直接引用 CurrentDocumentType = selectedDocumentType?.Clone() ?? new DocumentType(); OnPropertyChanged(nameof(SelectedDocumentType)); } } private DocumentType currentDocumentType; public DocumentType CurrentDocumentType { get { return currentDocumentType; } set { currentDocumentType = value; OnPropertyChanged(nameof(CurrentDocumentType)); } }
3. 添加更新命令及执行逻辑
实现ICommand处理更新操作,将副本值同步到原对象:
// 可使用Prism/MvvmLight的RelayCommand,或自定义实现 public ICommand UpdateCommand { get; } public YourViewModel() { UpdateCommand = new RelayCommand(ExecuteUpdate); } private void ExecuteUpdate() { if (SelectedDocumentType == null || CurrentDocumentType == null) return; // 将副本属性同步到原对象 SelectedDocumentType.DocumentTypeName = CurrentDocumentType.DocumentTypeName; // 其他属性同步逻辑 // 触发属性变更通知,让DataGrid刷新显示 OnPropertyChanged(nameof(SelectedDocumentType)); // 可选:更新后重置编辑副本为原对象的拷贝,保持编辑状态 // CurrentDocumentType = SelectedDocumentType.Clone(); }
4. 在XAML中添加更新按钮
绑定更新命令:
<Button Content="Update" Command="{Binding UpdateCommand}" Margin="0 10"/>
效果说明
- 选中DataGrid行时,
CurrentDocumentType被赋值为选中对象的副本,TextBox修改的是副本数据,不会影响DataGrid实时显示。 - 点击Update按钮后,副本属性值同步到原对象,DataGrid触发更新,显示修改后的内容。
内容的提问来源于stack exchange,提问作者YMRP
相关产品推荐
相关产品推荐

