WPF DataGrid绑定ViewModel失败及ItemsSource报错求助
WPF DataGrid绑定问题排查与解决
问题现象
- DataGrid绑定ViewModel后始终无数据显示,但按钮、TextBlock的绑定功能正常,可正常访问和操作对应数据
- 运行时抛出错误:
System.InvalidOperationException: "Items collection must be empty before using ItemsSource."
错误原因
- 列定义位置错误:直接将
DataGridTextColumn放在DataGrid根标签内,会被WPF识别为向Items集合添加元素,与设置的ItemsSource冲突,触发报错。 - 属性类型不匹配:ViewModel中
Workers属性声明为IObservable<WorkerDTO>,但实际赋值为ObservableCollection<WorkerDTO>。IObservable<T>是事件订阅接口,并非WPFItemsSource所需的集合类型,导致绑定无法正确解析数据。
修复步骤
- 将DataGrid的列定义嵌套到
<DataGrid.Columns>标签内部,避免与ItemsSource冲突。 - 修改ViewModel中
Workers属性的类型为ObservableCollection<WorkerDTO>,确保绑定能正确识别集合。 - 修正列的
Header文本(原代码所有列Header均为FirstName,属于笔误)。
修正后代码
XAML代码
<Page x:Class="Workers_managment_entity_framework_practice.workers_viewing_page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Workers_managment_entity_framework_practice" mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="800" Title="workers_viewing_page"> <Grid Background="Black"> <Grid.RowDefinitions> <RowDefinition Height="3*"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <DataGrid x:Name="workersBoard" ItemsSource="{Binding Workers}"> <DataGrid.Columns> <DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}"></DataGridTextColumn> <DataGridTextColumn Header="LastName" Binding="{Binding LastName}"></DataGridTextColumn> <DataGridTextColumn Header="Salary" Binding="{Binding Salary}"></DataGridTextColumn> <DataGridTextColumn Header="WorkExperience" Binding="{Binding WorkExperience}"></DataGridTextColumn> </DataGrid.Columns> </DataGrid> </Grid> </Page>
ViewModel代码
public class WorkersViewModel { public readonly WorkersService _service; public ObservableCollection<WorkerDTO> Workers { get; set; } public WorkersViewModel() { string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["default"].ConnectionString; _service = new WorkersService(connectionString); Workers = new ObservableCollection<WorkerDTO>(_service.GetAll()); } }
额外检查项
- 确认
WorkerDTO类中的FirstName、LastName等属性均为公共可访问属性,且包含get访问器,否则绑定无法读取属性值。 - 若后续需要动态更新集合数据,
ObservableCollection<T>会自动通知UI更新,无需额外处理。
内容的提问来源于stack exchange,提问作者Yaroslavio
相关产品推荐
相关产品推荐

