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

WPF DataGrid修改ObservableCollection项后UI不更新,MVVM下如何解决?

解决WPF DataGrid修改ObservableCollection项后UI不实时更新的问题

我太懂你遇到的这个坑了——明明数据已经改了,DataGrid却非要等点列头才刷新,这在MVVM模式下确实挺闹心的。其实问题根源很明确,咱们一步步来解决:

核心原因:实体类没实现属性变更通知

ObservableCollection只能帮你通知UI集合本身的结构变化(比如新增、删除、替换集合项),但它管不了集合里每个对象内部属性的变化。你的Person类只是个普通的POCO类,没有实现INotifyPropertyChanged接口,所以当你修改FirstName时,UI根本收不到“这个属性变了”的信号,自然不会主动刷新。

解决方案:让Person类实现INotifyPropertyChanged

既然你的VM已经继承了Notifier(我猜这个基类就是封装了INotifyPropertyChanged的),那直接让Person也继承它就行;如果Notifier没做这个封装,就自己实现接口。

修改后的Person类代码

// 假设Notifier是封装了INotifyPropertyChanged的自定义基类
public class Person : Notifier 
{
    private string _firstName;
    public string FirstName 
    { 
        get { return _firstName; } 
        set { _firstName = value; OnPropertyChanged(nameof(FirstName)); } 
    }

    private string _lastName;
    public string LastName 
    { 
        get { return _lastName; } 
        set { _lastName = value; OnPropertyChanged(nameof(LastName)); } 
    }
}

如果你的Notifier没封装接口,就手动实现:

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private string _firstName;
    public string FirstName 
    { 
        get { return _firstName; } 
        set { _firstName = value; OnPropertyChanged(); } 
    }

    private string _lastName;
    public string LastName 
    { 
        get { return _lastName; } 
        set { _lastName = value; OnPropertyChanged(); } 
    }
}

清理冗余代码

现在属性变更会自动通知UI了,你原来写的强制刷新代码就没必要留着了,简化SetSelected方法:

private void SetSelected(object parameter = null)
{
    SelectedPerson.FirstName = String1;
    // 下面两行可以删掉了,不用再强制触发setter
    // SelectedPerson = SelectedPerson; 
    // DataSource = DataSource; 
}

顺便修复VM里的小bug

你的String1属性setter里有个错误:OnPropertyChanged(String1)会把当前的字符串值当成属性名传进去,这会导致String1变更时UI也收不到通知,赶紧修正:

public string String1
{
    get { return string1; }
    set { string1 = value; OnPropertyChanged(nameof(String1)); } // 这里改成属性名
}

总结一下

WPF的DataGrid要实时刷新,需要两个层面的通知:

  • ObservableCollection负责集合结构变化的通知(增删改项)
  • 集合内的实体类负责自身属性变化的通知(实现INotifyPropertyChanged)
    两者配合起来,UI才能实时响应所有数据变化。

内容的提问来源于stack exchange,提问作者Moonling

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:45:48