Datagrid未在WPF中显示数据 [英] Datagrid is not showing data in WPF
问题描述
xaml:
< Window x:Class =MainWindow
xmlns =http://schemas.microsoft.com/winfx/2006/ xaml / presentation
xmlns:x =http://schemas.microsoft.com/winfx/2006/xaml
Title =MainWindowHeight =350Width =525
Loaded =Window_Loaded>
< Grid>
< Grid.RowDefinitions>
< RowDefinition Height =272 */>
< RowDefinition Height =71 */>
< /Grid.RowDefinitions>
< Button Content =SynchronizeName =btnsyncGrid.Row =1FontSize =40FontFamily =Times New RomanFontWeight =ExtraBold/>
< DataGrid Name =dgEmpAutoGenerateColumns =FalseColumnWidth =*>
< DataGrid.Columns>
< DataGridTextColumn Header =EmpNoBinding ={Binding EmpNo}>< / DataGridTextColumn>
< DataGridTextColumn Header =EmpNameBinding ={Binding EmpName}>< / DataGridTextColumn>
< DataGridTextColumn Header =SalaryBinding ={Binding Salary}>< / DataGridTextColumn>
< DataGridTextColumn Header =DeptNameBinding ={Binding DeptName}>< / DataGridTextColumn>
< /DataGrid.Columns>
< / DataGrid>
< / Grid>
< / Window>
MainWindow.xaml.vb代码
Imports System.Collections.ObjectModel
Class MainWindow
公共职员>
Public EmpNo As String
Public EmpName As String
Public Salary As String
Public DeptName As String
结束班级
Dim empList As New ObservableCollection(员工人数)
Private Sub btnsync_Click( sender As System.Object,e As System.Windows.RoutedEventArgs)处理btnsync.Click
'empList.Add(New Employee()With {.EmpNo =2,。EmpName =Avinash ,.Salary =5000,。DeptName =Dev})
'dgEmp.Items.Refresh()
End Sub
Private Sub Window_Loaded(sender As System.Object,e As System.Windows.RoutedEventArgs)处理MyBase.Loaded
empLi st.Add(New Employee(){{EmpNo =2,。EmpName =Avinash,。Saalary =5000,。DeptName =Dev})
empList.Add (新员工(){.EmpNo =3,。EmpName =Avinash,.Salary =5000,. DeptName =Dev})
empList.Add(新员工) ()使用{.EmpNo =4,。EmpName =Avinash,.Salary =5000,. DeptName =Dev})
dgEmp.ItemsSource = empList
End Sub
Private Sub dgEmp_SelectionChanged(sender As System.Object,e As System.Windows.Controls.SelectionChangedEventArgs)处理dgEmp.SelectionChanged
结束子
结束班
我尝试过:
我验证了,物品来源有数据,但没有显示在dataGrid上。
digimanus [ ^ ]在上面的评论中部分正确。
首先,要让DataGrid查看员工集合,DataBinding需要将集合视为MainWindow的属性:
公共 属性 empList = 新 ObservableCollection( of Employee)
接下来,您将在Debug Output窗口中发现一堆DataBinding错误。以下是一个例子:
System.Windows.Data错误:40:BindingExpression路径错误:'对象'''员工'上找不到'EmpNo'属性(的HashCode = 62835574)。 BindingExpression:路径= EMPNO; DataItem ='Employee'(HashCode = 62835574); target元素是'TextBlock'(Name =''); target属性是'Text'(类型'String')
这是因为DataBinding正在寻找属性
而不是字段
。因此修复非常简单:
公共 类员工
公共 属性 EmpNo As 字符串
公共 属性 EmpName 作为 字符串
公共 属性薪水作为 字符串
公共 属性 DeptName 作为 < span class =code-keyword>字符串
结束 类
下一个问题是你会看到在DataGrid中加载两次的项目。这样做的原因是您正在XAML和后面的代码中监听Windows.Loaded
事件。你需要选择保留哪一个。我建议从XAML中删除以符合您对项目进行编码的方式。
您将拥有的最后一个问题是,如果您更新了任何属性Employee
类,它们不会反映为Employee
类未实现INotifyPropertyChanged
界面。
因此,您更正的项目将如下所示:
< 窗口 x:Class = MainWindow
xmlns = http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns :x = http://schemas.microsoft.com/winfx/2006/xaml
< span class =code-attribute> xmlns:d = http://schemas.microsoft.com/expression/blend/2008
xmlns:mc = http://schemas.openxmlformats.org/markup-compatibility/2006
mc:可忽略 = d
标题 = MainWindow 高度 =350 宽度 = 525 >
< 网格 >
< Grid.RowDefinitions >
< RowDefinition < span class =code-attribute>高度 = 272 * / >
< RowDefinition 高度 = 71 * / >
< / Grid.RowDefinitions >
< ; 按钮 内容 < span class =code-keyword> = 同步 名称 = btnsync Grid.Row = 1 FontSize = 40 FontFamily = Times New Roman FontWeight = ExtraBold / >
< DataGrid 名称 = dgEmp AutoGenerateColumns = False ColumnWidth = * >
< DataGrid.Columns >
< DataGridTextColumn 标题 = EmpNo 绑定 = {Binding EmpNo} > < / DataGridTextColumn >
< DataGridTextColumn 跨度> < span class =code-attribute> 标题 = EmpName Binding = {Binding EmpName} > < / DataGridTextColumn >
< DataGridTextColumn 标题 = 薪水 Binding = {Binding Salary} > < / DataGridTextColumn >
< DataGridTextColumn 标题 = DeptName 绑定 = {Binding DeptName} > < / DataGridTextColumn >
< / DataGrid.Columns >
< / DataGrid >
< / Grid >
< / Window >
和代码隐藏:
进口 System.Collections.ObjectModel
Class MainWindow
Public 属性 empList = 新 ObservableCollection( of 员工)
私有 Sub btnsync_Click(sender As System。 Object ,e As System.Windows.RoutedEventArgs) Handles btnsync.Click
' empList.Add(New Employee(){{EmpNo =2,。EmpName =Avinash,.Salary =5000 ,.DeptName =Dev})
' dgEmp.Items.Refresh()
结束 Sub
Private Sub Window_Loaded(sender As System。 Object ,e As System.Windows.RoutedEventArgs)句柄 MyBase .Loaded
empList.Add( New Employee() {.EmpNo = 2,。EmpName = Avinash,.Salary = 5000, .DeptName = Dev})
empList.Add(新 Employee()使用 {.EmpNo = 3,。EmpName = Avinash,.Salary = 5000,。DeptName = Dev})
empList.Add( New Employee()使用 {.EmpNo = 4,。EmpName = < span class =code-str ing> Avinash,.Salary = 5000,。DeptName = Dev})
dgEmp.ItemsSource = empList
结束 Sub
私有 Sub dgEmp_SelectionChanged(发件人作为系统。对象,e As System.Windows.Controls.SelectionChangedEventArgs)句柄 dgEmp.SelectionChanged
结束 Sub
结束 类
公共 类 Empl oyee
公共 属性 EmpNo As 字符串
公开 属性 EmpName 作为 字符串
公共 属性薪资作为 字符串
公开 属性 DeptName As 字符串
结束 类
我建议熟悉WPF中使用的DataBinding系统: Microsoft Docs:数据B. inding(WPF) [ ^
xaml :
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="272*"/> <RowDefinition Height="71*"/> </Grid.RowDefinitions> <Button Content="Synchronize" Name="btnsync" Grid.Row="1" FontSize="40" FontFamily="Times New Roman" FontWeight="ExtraBold"/> <DataGrid Name="dgEmp" AutoGenerateColumns="False" ColumnWidth="*"> <DataGrid.Columns> <DataGridTextColumn Header="EmpNo" Binding="{Binding EmpNo}" ></DataGridTextColumn> <DataGridTextColumn Header="EmpName" Binding="{Binding EmpName}" ></DataGridTextColumn> <DataGridTextColumn Header="Salary" Binding="{Binding Salary}" ></DataGridTextColumn> <DataGridTextColumn Header="DeptName" Binding="{Binding DeptName}" ></DataGridTextColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
MainWindow.xaml.vb code
Imports System.Collections.ObjectModel
Class MainWindow
Public Class Employee
Public EmpNo As String
Public EmpName As String
Public Salary As String
Public DeptName As String
End Class
Dim empList As New ObservableCollection(Of Employee)
Private Sub btnsync_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnsync.Click
'empList.Add(New Employee() With {.EmpNo = "2", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"})
'dgEmp.Items.Refresh()
End Sub
Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
empList.Add(New Employee() With {.EmpNo = "2", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"})
empList.Add(New Employee() With {.EmpNo = "3", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"})
empList.Add(New Employee() With {.EmpNo = "4", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"})
dgEmp.ItemsSource = empList
End Sub
Private Sub dgEmp_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles dgEmp.SelectionChanged
End Sub
End Class
What I have tried:
I verified, Items source is having data but it is not shown on dataGrid.
digimanus[^] is partially correct in his comment above.
Firstly, for the DataGrid to see the collection of employees, the DataBinding needs to see the collection as a property of the MainWindow:
Public Property empList = New ObservableCollection(Of Employee)
Next, you will nee a bunch of DataBinding errors in the Debug Output window. Here is one as an example:
System.Windows.Data Error: 40 : BindingExpression path error: 'EmpNo' property not found on 'object' ''Employee' (HashCode=62835574)'. BindingExpression:Path=EmpNo; DataItem='Employee' (HashCode=62835574); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
This is because DataBinding is looking forProperties
and notFields
. So the fix is quite simple:
Public Class Employee Public Property EmpNo As String Public Property EmpName As String Public Property Salary As String Public Property DeptName As String End Class
The next problem is that you will see the items loaded twice in the DataGrid. The reason for this is that you are listening to theWindows.Loaded
event both in the XAML and the code behind. You need to select which one to keep. I would recommend removing from the XAML to keep in line with how you are coding your project.
The last issue that you will have is if you update any properties on youEmployee
class, they won't be reflected as theEmployee
class does not implement theINotifyPropertyChanged
Interface.
So, your corrected project will look like this:
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="272*"/> <RowDefinition Height="71*"/> </Grid.RowDefinitions> <Button Content="Synchronize" Name="btnsync" Grid.Row="1" FontSize="40" FontFamily="Times New Roman" FontWeight="ExtraBold"/> <DataGrid Name="dgEmp" AutoGenerateColumns="False" ColumnWidth="*"> <DataGrid.Columns> <DataGridTextColumn Header="EmpNo" Binding="{Binding EmpNo}" ></DataGridTextColumn> <DataGridTextColumn Header="EmpName" Binding="{Binding EmpName}" ></DataGridTextColumn> <DataGridTextColumn Header="Salary" Binding="{Binding Salary}" ></DataGridTextColumn> <DataGridTextColumn Header="DeptName" Binding="{Binding DeptName}" ></DataGridTextColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
and the code-behind:
Imports System.Collections.ObjectModel Class MainWindow Public Property empList = New ObservableCollection(Of Employee) Private Sub btnsync_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnsync.Click 'empList.Add(New Employee() With {.EmpNo = "2", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"}) 'dgEmp.Items.Refresh() End Sub Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded empList.Add(New Employee() With {.EmpNo = "2", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"}) empList.Add(New Employee() With {.EmpNo = "3", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"}) empList.Add(New Employee() With {.EmpNo = "4", .EmpName = "Avinash", .Salary = "5000", .DeptName = "Dev"}) dgEmp.ItemsSource = empList End Sub Private Sub dgEmp_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles dgEmp.SelectionChanged End Sub End Class Public Class Employee Public Property EmpNo As String Public Property EmpName As String Public Property Salary As String Public Property DeptName As String End Class
I would recommend getting familiar with DataBinding system used in WPF: Microsoft Docs: Data Binding (WPF)[^]
这篇关于Datagrid未在WPF中显示数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!