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
相关产品推荐
相关产品推荐

