WPF嵌套DataGrid数据绑定失败问题求助
我在学习C#和WPF,做一个工作用的个人项目,要实现嵌套DataGrid:主DataGrid展示SQL查询的文章数据,点击行展开后显示对应的LigneArticle数据。调试时确认变量里有数据,但子DataGrid始终没内容。用ItemsControl绑定同一集合能正常显示,但因为需要排序功能必须用DataGrid,试了很多次还是解决不了。
以下是针对性的排查和解决步骤:
核对子DataGrid的ItemsSource绑定路径
主DataGrid的行数据上下文是单条文章对象,子DataGrid的ItemsSource必须绑定到该对象下的LigneArticle集合属性。务必确认绑定路径的属性名拼写完全正确,比如文章类的集合属性叫LigneArticles,绑定就写{Binding LigneArticles}。参考XAML片段:
<DataGrid Name="MainDataGrid" AutoGenerateColumns="False"> <!-- 主DataGrid列定义 --> <DataGridTextColumn Header="文章ID" Binding="{Binding ArticleId}" /> <DataGridTextColumn Header="文章标题" Binding="{Binding Title}" /> <DataGrid.RowDetailsTemplate> <DataTemplate> <DataGrid ItemsSource="{Binding LigneArticles}" AutoGenerateColumns="False"> <DataGridTextColumn Header="明细ID" Binding="{Binding Id}" /> <DataGridTextColumn Header="明细内容" Binding="{Binding Content}" /> </DataGrid> </DataTemplate> </DataGrid.RowDetailsTemplate> </DataGrid>保证集合属性触发属性变更通知
如果文章类的LigneArticles集合是在主数据加载完成后才赋值的,必须让文章类实现INotifyPropertyChanged接口,赋值时触发PropertyChanged事件。否则WPF无法感知到数据更新,就算后台有值,UI也不会刷新。参考后台代码片段:
public class Article : INotifyPropertyChanged { public int ArticleId { get; set; } public string Title { get; set; } private ObservableCollection<LigneArticle> _ligneArticles; public ObservableCollection<LigneArticle> LigneArticles { get => _ligneArticles; set { _ligneArticles = value; OnPropertyChanged(nameof(LigneArticles)); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class LigneArticle { public int Id { get; set; } public string Content { get; set; } }改用ObservableCollection作为子集合类型
子集合必须用ObservableCollection<T>,它自带集合元素添加、删除、替换的变更通知。如果之前用的是普通List<T>,替换成ObservableCollection<T>就能让UI感知到集合变化。检查子DataGrid的列配置
- 如果
AutoGenerateColumns设为False,要确认所有列的Binding路径和LigneArticle类的公共属性名完全匹配(WPF绑定区分大小写)。 - 如果设为
True,要确保LigneArticle类的属性都是公共(public)的,私有属性不会自动生成列。
- 如果
查看绑定错误日志
打开Visual Studio的输出窗口(调试时),过滤“绑定”相关的日志,里面会明确提示绑定失败的原因,比如“找不到属性LigneArticle”“目标属性不可访问”等,这些信息能快速定位问题。
内容的提问来源于stack exchange,提问作者ZeDeRo

