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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:27:23