WPF:绑定含数据的ObservableCollection后DataGrid为何仍为空?
问题解决:WPF DataGrid绑定ObservableCollection后显示为空
核心问题分析
你的DataGrid显示为空主要有三个关键问题:
1. 集合是字段而非属性,无法被WPF绑定识别
WPF的数据绑定仅支持属性(带get/set访问器),你当前的ALLTASKLIST是字段:
public ObservableCollection<ThePart1> ALLTASKLIST = new ObservableCollection<ThePart1>();
而且在Window_Loaded中直接重新赋值了集合引用,这会导致绑定丢失,因为没有通知UI集合发生了变化。
2. DataGrid未设置ItemsSource
你注释掉了MainDatagrid.ItemsSource = ALLTASKLIST;,同时XAML中也没有给DataGrid绑定ItemsSource,导致DataGrid没有数据源。
3. DataGridComboBoxColumn的ItemsSource绑定上下文错误
DataGrid的每一行数据上下文是ThePart1的单个实例,直接绑定ALLTASKLIST会找不到这个集合,需要指定绑定的源为窗口的DataContext。
修复步骤
步骤1:让MainWindow实现INotifyPropertyChanged,将ALLTASKLIST改为属性
修改后台代码,让窗口类实现属性变更通知,并把集合改成带通知的属性:
public partial class MainWindow : Window, INotifyPropertyChanged { NEGIN1401Entities dbms = null; // 改为属性,并支持通知 private ObservableCollection<ThePart1> _allTaskList; public ObservableCollection<ThePart1> ALLTASKLIST { get { return _allTaskList; } set { _allTaskList = value; OnPropertyChanged(nameof(ALLTASKLIST)); } } public MainWindow() { InitializeComponent(); DataContext = this; // 初始化集合 ALLTASKLIST = new ObservableCollection<ThePart1>(); } private void Window_Loaded(object sender, RoutedEventArgs e) { dbms = new NEGIN1401Entities(Publications.TheENTTConnectionString); // 赋值给属性,触发通知 ALLTASKLIST = dbms.Database.SqlQuery<ThePart1>("SELECT * FROM TCOD_ANBAR").ToObservableCollection(); } // 属性变更通知实现 public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // 保留原有的ThePart1类不变 public class ThePart1 : INotifyPropertyChanged { private int? _CODE; private string _NAMES; private int? _KIND; private int? _idd; public int? CODE { get { return _CODE; } set { _CODE = value; OnPropertyChanged("CODE"); } } public string NAMES { get { return _NAMES; } set { _NAMES = value; OnPropertyChanged("NAMES"); } } public int? KIND { get { return _KIND; } set { _KIND = value; OnPropertyChanged("KIND"); } } public int? idd { get { return _idd; } set { _idd = value; OnPropertyChanged("idd"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string strCaller = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(strCaller)); } } }
步骤2:给DataGrid绑定ItemsSource并修正ComboBoxColumn绑定
修改XAML中的DataGrid,添加ItemsSource绑定,并修正ComboBoxColumn的数据源绑定:
<DataGrid x:Name="MainDatagrid" ItemsSource="{Binding ALLTASKLIST}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridComboBoxColumn Header="CMB"> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="ComboBox"> <!-- 通过RelativeSource找到窗口的DataContext,绑定ALLTASKLIST --> <Setter Property="ItemsSource" Value="{Binding Path=DataContext.ALLTASKLIST, RelativeSource={RelativeSource AncestorType=DataGrid}}" /> <Setter Property="DisplayMemberPath" Value="NAMES" /> <Setter Property="SelectedValuePath" Value="CODE" /> <!-- 绑定当前行的CODE字段作为选中值 --> <Setter Property="SelectedValue" Value="{Binding CODE}" /> </Style> </DataGridComboBoxColumn.EditingElementStyle> <!-- 添加非编辑状态的显示样式,确保未编辑时显示对应名称 --> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="TextBlock"> <Setter Property="Text" Value="{Binding NAMES}" /> </Style> </DataGridComboBoxColumn.ElementStyle> </DataGridComboBoxColumn> <!-- 可添加其他列展示数据 --> <DataGridTextColumn Header="编码" Binding="{Binding CODE}" /> <DataGridTextColumn Header="类型" Binding="{Binding KIND}" /> </DataGrid.Columns> </DataGrid>
关键说明
- WPF绑定只能识别属性,字段无法被绑定系统检测到,必须将集合改为带get/set的属性。
- 当重新赋值集合引用时,需要触发
PropertyChanged通知,否则UI不会更新。 - DataGridComboBoxColumn的ItemsSource需要指定正确的绑定源,因为行的DataContext是单个数据项,不是窗口的DataContext,所以要用
RelativeSource来找到窗口的集合。
内容的提问来源于stack exchange,提问作者Maj Majidi
相关产品推荐
相关产品推荐

