WPF DataGrid添加数据源项后运行时不实时更新问题求助
解决WPF DataGrid添加数据后无法实时刷新的问题
问题根源
你的代码存在两个核心问题导致DataGrid无法实时刷新:
LoadPart方法直接修改字段而非属性:你在LoadPart里直接给_parts字段赋值新的ObservableCollection,但没有触发Parts属性的PropertyChanged事件,UI无法感知数据源变化。- 每次加载数据创建新集合:即便触发了属性变更,新集合会导致DataGrid丢失原有状态(如选中项、滚动位置),这也是你切换视图后状态丢失的原因。
而模拟集合能正常刷新,是因为它始终是同一个ObservableCollection实例,添加项时会自动触发CollectionChanged事件通知UI。
修复方案
方案1:更新现有集合(推荐,保留DataGrid状态)
修改LoadPart方法,清空现有集合并添加新数据,利用ObservableCollection自带的CollectionChanged事件自动通知UI刷新,同时保留DataGrid的当前状态:
public void LoadPart() { // 清空现有集合 _parts.Clear(); // 从数据库获取数据并逐个添加到现有集合 var newParts = PartDataAccess.GetPart(); foreach (var part in newParts) { _parts.Add(part); } }
如果觉得循环添加麻烦,可以给ObservableCollection写一个扩展方法简化:
public static class ObservableCollectionExtensions { public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items) { foreach (var item in items) { collection.Add(item); } } }
然后LoadPart可以改成:
public void LoadPart() { _parts.Clear(); _parts.AddRange(PartDataAccess.GetPart()); }
方案2:重新创建集合并触发属性变更(不推荐,丢失状态)
如果必须重新创建集合,要通过Parts属性的setter赋值,触发PropertyChanged事件:
public void LoadPart() { // 通过属性赋值触发PropertyChanged Parts = new ObservableCollection<Part>(PartDataAccess.GetPart()); }
此方法会导致DataGrid重新绑定,丢失之前的选中项、滚动位置等状态,仅适合不需要保留状态的场景。
额外优化建议
- 确保
Part类实现INotifyPropertyChanged:如果后续需要修改DataGrid中的项并实时刷新,Part类必须实现该接口,否则单个属性变更无法通知UI。 - 复用DbContext(可选):如果频繁操作数据库,可以考虑复用DbContext而非每次创建新实例,同时利用
DbSet.Local属性直接绑定,减少手动刷新的需求:// 在ViewModel中持有DbContext实例(注意生命周期管理) private readonly MikeInventoryContext _dbContext; public PartViewModel() { _dbContext = new MikeInventoryContext(); _parts = new ObservableCollection<Part>(_dbContext.Parts.Local); // 监听DbContext的变更事件,自动同步集合 _dbContext.ChangeTracker.StateChanged += (s, e) => { if (e.NewState == EntityState.Added || e.NewState == EntityState.Deleted) { _parts.Clear(); _parts.AddRange(_dbContext.Parts.Local); } }; }
内容的提问来源于stack exchange,提问作者ThinkinCap
相关产品推荐
相关产品推荐

