Datagrid未在WPF中显示数据 [英] Datagrid is not showing data in WPF

查看:77
本文介绍了Datagrid未在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 for Properties and not Fields. 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 the Windows.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 you Employee class, they won't be reflected as the Employee class does not implement the INotifyPropertyChanged 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆