WPF中DataGrid绑定ObservableCollection不更新但其他绑定正常如何解决
问题根本原因
你的Player类没有实现WPF绑定要求的INotifyPropertyChanged接口。ObservableCollection<T>只能通知集合本身的增、删、元素替换这类变化,无法感知集合内部存储的元素自身属性的变更,所以你修改Player的Points值后,UI端收不到变更通知,自然不会更新。
补充说明:你看到Label能正常更新是因为你每次切换回合时都手动给lbActivePlayer.DataContext赋了新值,相当于强制触发了绑定刷新,而DataGrid绑定的集合元素属性变更没有通知机制,所以不会自动刷新。
修复方案
- 修改
Player类,实现INotifyPropertyChanged接口,在Points属性变更时触发属性通知,同时因为DisplayPts是依赖Points的计算属性,Points更新时需要同步通知DisplayPts也发生了变更:
using System.ComponentModel; using System.Runtime.CompilerServices; public class Player : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; // 通知属性变更的辅助方法 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public Player(string name) { Name = name; Points = 0; } private string _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(); OnPropertyChanged(nameof(DisplayName)); } } private int _points; public int Points { get => _points; set { _points = value; OnPropertyChanged(); OnPropertyChanged(nameof(DisplayPts)); } } public string DisplayName => $"{Name} : "; public string DisplayPts => $"{Points} pts"; public void AddPts(int pts) { Points += pts; } }
- 修正代码笔误:Game构造函数传入的参数是
listP,你初始化ObservableCollection时误用了listeJ,应该改成:
ListPlayers = new ObservableCollection<Player>(listP);
- 冗余代码可删除:
NewTurn方法里不需要每次都给dgDisplay.DataContext赋值,只需要在窗口初始化时赋值一次即可,重复赋值不会解决更新问题也没有意义。
内容的提问来源于stack exchange,提问作者DreamyT
相关产品推荐
相关产品推荐

