WPF中DataGrid绑定ObservableCollection后数据更新失效问题
问题核心原因
我一眼就看出来了——你遇到的DataGrid不更新的问题,根源在于你的ViewModel没有实现INotifyPropertyChanged接口,而且TimeSheetList属性的setter没有触发属性变更通知。
咱们拆解下:
ObservableCollection本身是实现了INotifyCollectionChanged的,所以你对集合做Clear、Add、RemoveAt这类操作时,UI能自动感知到(这就是你测试RemoveAt(0)有效的原因)。- 但当你直接给
TimeSheetList赋值一个全新的ObservableCollection对象时,这是属性的引用发生了变化,而绑定系统根本不知道这件事——因为你的ViewModel没有告诉它“这个属性变了”。 - 构造函数里赋值正常,是因为那时候绑定系统刚初始化,会读取一次属性的初始值;后续重新赋值时没有通知,绑定系统还在盯着原来的那个旧集合。
至于你说的加Mode=TwoWay临时生效,那只是个巧合——TwoWay模式下某些UI操作可能会意外触发绑定重新评估,但这完全不可靠,不是正确的解决方式。
两种解决方案
方案一:给ViewModel实现INotifyPropertyChanged(推荐,符合MVVM规范)
这是最规范的做法,也是你之前其他窗体正常工作的原因(大概率那些窗体的ViewModel已经实现了这个接口)。
修改你的ViewModel代码:
- 让ViewModel继承
INotifyPropertyChanged接口 - 给
TimeSheetList的setter添加属性变更通知
public class YourViewModel : INotifyPropertyChanged // 替换成你的ViewModel实际类名 { private ObservableCollection<TimeSheetByEmployeeModel> _TimeSheetList = new ObservableCollection<TimeSheetByEmployeeModel>(); public ObservableCollection<TimeSheetByEmployeeModel> TimeSheetList { get { return _TimeSheetList; } set { if (_TimeSheetList != value) { _TimeSheetList = value; RaisePropertyChange(nameof(TimeSheetList)); // 用nameof避免硬编码字符串,更安全 } } } // 实现INotifyPropertyChanged的事件和触发方法 public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChange(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // 你的其他ViewModel代码... }
这样以后每次给TimeSheetList赋值新集合时,都会通知绑定系统更新UI,完美解决问题。
方案二:不替换集合,只更新集合内容(快速修复)
如果你不想修改ViewModel的结构,可以直接复用现有集合,清空后添加新数据——利用ObservableCollection本身的集合变更通知:
修改你的Ok_Click方法:
private void Ok_Click(object sender, RoutedEventArgs e) { try { TimeSheetList.Clear(); string EmployeeID = cboemployee.SelectedValue.ToString(); var newTimeSheetData = TimeSheetByEmployeeDataAccessor.GetTimeSheetByEmployee_ByFromTo( dtpfrom.SelectedDate.GetValueOrDefault(), dtpto.SelectedDate.GetValueOrDefault(), EmployeeID); // 把新数据逐个添加到现有集合中 foreach (var item in newTimeSheetData) { TimeSheetList.Add(item); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
这种方式不需要修改ViewModel,直接利用ObservableCollection的特性就能让UI同步更新。
内容的提问来源于stack exchange,提问作者user9152389
相关产品推荐
相关产品推荐

