.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不会自动将列与数据源对象的属性关联,必须显式指定每个列要绑定的属性名。
修改步骤:
- 修改
InitialiserColonnesDataGridView方法,给每个数据列添加DataPropertyName,使其与Produit类的属性名一一对应。 - 可以用辅助方法简化列的创建,避免重复代码。
修改后的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
相关产品推荐
相关产品推荐

