You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET应用DataGridView行数正确但单元格无数据问题求助

问题:DataGridView绑定API数据后单元格为空

我在.NET WinForms应用中从API提取JSON数据,反序列化后绑定到DataGridView控件,但单元格内容始终为空。已经通过MsgBox确认API返回的JSON数据正常,反序列化后的对象列表也有数据,却无法定位问题所在。

相关代码如下:

Imports System.Data.OleDb
Imports Newtonsoft.Json
Imports System.Net.Http
Imports System.Text

Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.WindowState = FormWindowState.Maximized
        DataGridView1.Dock = DockStyle.Fill

        Dim margin As New Padding(100, 500, 100, 250)
        Me.Margin = margin

        DataGridView1.AutoGenerateColumns = False
        InitialiserColonnesDataGridView()
        RefreshData()
        AdjustButtonPosition()
    End Sub

    Private Sub InitialiserColonnesDataGridView()

        DataGridView1.Columns.Clear()


        Dim deleteButtonColumn As New DataGridViewButtonColumn()
        deleteButtonColumn.HeaderText = "Supprimer"
        deleteButtonColumn.Name = "DeleteButtonColumn"
        deleteButtonColumn.Text = "Supprimer"
        deleteButtonColumn.UseColumnTextForButtonValue = True
        deleteButtonColumn.DefaultCellStyle.BackColor = Color.Red
        DataGridView1.Columns.Insert(0, deleteButtonColumn)


        Dim editButtonColumn As New DataGridViewButtonColumn()
        editButtonColumn.HeaderText = "Modifier"
        editButtonColumn.Name = "EditButtonColumn"
        editButtonColumn.Text = "Modifier"
        editButtonColumn.UseColumnTextForButtonValue = True
        editButtonColumn.DefaultCellStyle.BackColor = Color.Orange
        DataGridView1.Columns.Insert(1, editButtonColumn)


        DataGridView1.Columns.Add("id", "ID")
        DataGridView1.Columns.Add("nom", "Nom")
        DataGridView1.Columns.Add("prix", "Prix")
        DataGridView1.Columns.Add("description", "Description")
        DataGridView1.Columns.Add("annee", "Année")
        DataGridView1.Columns.Add("quantite_stock", "Quantité en stock")
        DataGridView1.Columns.Add("reference", "Référence")
        DataGridView1.Columns.Add("fournisseur", "Fournisseur")
        DataGridView1.Columns.Add("info", "Info")
        DataGridView1.Columns.Add("maison", "Maison")
        DataGridView1.Columns.Add("famille", "Famille")
        DataGridView1.Columns.Add("region", "Région")
        DataGridView1.Columns.Add("image", "Image")

    End Sub

    Private Sub AdjustButtonPosition()
        Dim bottomMargin As Integer = 10
        Dim buttonLocation As New Point(Me.ClientSize.Width - Button1.Width - 10, Me.ClientSize.Height - Button1.Height - bottomMargin)
        Button1.Location = buttonLocation
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Me.Hide()
        Dim ajoutVinForm As New AjoutVin()
        ajoutVinForm.ShowDialog()
        Me.Show()
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        AdjustButtonPosition()
        RefreshData()
    End Sub

    Private Async Sub RefreshData()
        Dim apiUrl As String = Config.BaseApiUrl & "/produit"

        Using client As New HttpClient()
            Dim response As HttpResponseMessage = Await client.GetAsync(apiUrl)
            If response.IsSuccessStatusCode Then
                Dim jsonString As String = Await response.Content.ReadAsStringAsync()
                Dim produits As List(Of Produit) = JsonConvert.DeserializeObject(Of List(Of Produit))(jsonString)
                DataGridView1.DataSource = produits
            Else
                MessageBox.Show("Une erreur est survenue lors du chargement des données depuis l'API.")
            End If
        End Using
    End Sub

    Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
        If e.RowIndex >= 0 Then
            If e.ColumnIndex = DataGridView1.Columns("DeleteButtonColumn").Index Then
                Dim confirmationResult As DialogResult = MessageBox.Show("Voulez-vous vraiment supprimer cet enregistrement ?", "Confirmation de suppression", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                If confirmationResult = DialogResult.Yes Then
                    Dim idToDelete As Integer = Convert.ToInt32(DataGridView1.Rows(e.RowIndex).Cells("id").Value)
                    DeleteRecord(idToDelete)
                End If
            ElseIf e.ColumnIndex = DataGridView1.Columns("EditButtonColumn").Index Then
                Dim confirmationResult As DialogResult = MessageBox.Show("Voulez-vous vraiment modifier cet enregistrement ?", "Confirmation de modification", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                If confirmationResult = DialogResult.Yes Then
                    Dim idToEdit As Integer = Convert.ToInt32(DataGridView1.Rows(e.RowIndex).Cells("id").Value)
                    OpenModifierProduitForm(idToEdit)
                End If
            End If
        End If
    End Sub

    Private Sub OpenModifierProduitForm(id As Integer)
        Me.Hide()
        Dim modifierProduitForm As New modifierProduit(id)
        modifierProduitForm.ShowDialog()
        Me.Show()
    End Sub

    Private Async Sub DeleteRecord(id As Integer)
        Dim apiUrl As String = Config.BaseApiUrl & $"/produit/{id}"

        Using client As New HttpClient()
            Dim response As HttpResponseMessage = Await client.DeleteAsync(apiUrl)

            If response.IsSuccessStatusCode Then
                RefreshData()
                MessageBox.Show("Ligne supprimée avec succès.")
            Else
                MessageBox.Show("Erreur lors de la suppression de la ligne.")
            End If
        End Using
    End Sub

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Me.Hide()
        Commandes_Form.Show()
    End Sub
End Class


Public Class Produit
    Public Property id As Integer
    Public Property nom As String
    Public Property prix As Decimal
    Public Property description As String
    Public Property annee As Integer
    Public Property quantite_stock As Integer
    Public Property reference As String
    Public Property fournisseur As String
    Public Property info As String
    Public Property maison As String
    Public Property famille As String
    Public Property region As String
    Public Property image As String
End Class

解决方案

问题出在你设置了DataGridView1.AutoGenerateColumns = False,但手动添加的列没有指定DataPropertyName属性。当AutoGenerateColumns为False时,DataGridView不会自动将列与数据源对象的属性关联,必须显式指定每个列要绑定的属性名。

修改步骤:

  1. 修改InitialiserColonnesDataGridView方法,给每个数据列添加DataPropertyName,使其与Produit类的属性名一一对应。
  2. 可以用辅助方法简化列的创建,避免重复代码。

修改后的InitialiserColonnesDataGridView及辅助方法:

Private Sub InitialiserColonnesDataGridView()
    DataGridView1.Columns.Clear()

    ' 添加删除按钮列
    Dim deleteButtonColumn As New DataGridViewButtonColumn()
    deleteButtonColumn.HeaderText = "Supprimer"
    deleteButtonColumn.Name = "DeleteButtonColumn"
    deleteButtonColumn.Text = "Supprimer"
    deleteButtonColumn.UseColumnTextForButtonValue = True
    deleteButtonColumn.DefaultCellStyle.BackColor = Color.Red
    DataGridView1.Columns.Insert(0, deleteButtonColumn)

    ' 添加编辑按钮列
    Dim editButtonColumn As New DataGridViewButtonColumn()
    editButtonColumn.HeaderText = "Modifier"
    editButtonColumn.Name = "EditButtonColumn"
    editButtonColumn.Text = "Modifier"
    editButtonColumn.UseColumnTextForButtonValue = True
    editButtonColumn.DefaultCellStyle.BackColor = Color.Orange
    DataGridView1.Columns.Insert(1, editButtonColumn)

    ' 添加数据列并绑定对应属性
    AddDataColumn("id", "ID", "id")
    AddDataColumn("nom", "Nom", "nom")
    AddDataColumn("prix", "Prix", "prix")
    AddDataColumn("description", "Description", "description")
    AddDataColumn("annee", "Année", "annee")
    AddDataColumn("quantite_stock", "Quantité en stock", "quantite_stock")
    AddDataColumn("reference", "Référence", "reference")
    AddDataColumn("fournisseur", "Fournisseur", "fournisseur")
    AddDataColumn("info", "Info", "info")
    AddDataColumn("maison", "Maison", "maison")
    AddDataColumn("famille", "Famille", "famille")
    AddDataColumn("region", "Région", "region")
    AddDataColumn("image", "Image", "image")
End Sub

' 辅助方法:创建并添加绑定指定属性的数据列
Private Sub AddDataColumn(columnName As String, headerText As String, dataPropertyName As String)
    Dim column As New DataGridViewTextBoxColumn()
    column.Name = columnName
    column.HeaderText = headerText
    column.DataPropertyName = dataPropertyName ' 关键:指定要绑定的对象属性名
    DataGridView1.Columns.Add(column)
End Sub

验证补充:

如果仍有问题,可以在RefreshData方法中添加一行代码确认反序列化的数据数量:

Debug.WriteLine($"反序列化得到{produits.Count}条数据")

打开输出窗口查看数据数量,确保数据源确实有数据。


内容的提问来源于stack exchange,提问作者Miki Rikou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 07:55:55