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

VB.NET中如何将DataTable图片列正确填充至DataGridView图片列

代码问题分析与修正方案

问题描述

想请教以下代码是否存在问题,以及如何将带有图片列的DataTable正确填充到DataGridView中。

原代码

Private Sub LoadData()
    Dim item As New List(Of item())
    Grid.Bind(item)
End Sub
Private Sub FillDataTable(Avatar As Image, iRow As Integer, ByVal Codeproduct As String)
    Dim row As DataRow = _myTable.NewRow()
    row("") = Avatar
    row("No") = iRow
    row("Codeproduct") = Codeproduct
    _myTable.Rows.Add(row)
End Sub
Private Sub AddColumnsProgrammatically()
    Dim Col1 = New DataGridViewImageColumn()
    Dim Col2 = New DataGridViewTextBoxColumn()
    Dim Col3 = New DataGridViewTextBoxColumn()
    Col2.HeaderText = ""
    Col2.Name = "Column1"
    Col2.DataPropertyName = "{GetAvatar()}"
    Col2.HeaderText = "No"
    Col2.Name = "Column2"
    Col2.DataPropertyName = "No"
    Col3.HeaderText = "CodeProduct"
    Col3.Name = "Column3"
    Col3.DataPropertyName = "CodeProduct"
    Grid.Columns.AddRange(New DataGridViewColumn() {Col1, Col2, Col3})
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    AddColumnsProgrammatically()
    _myTable.Columns.Add("", GetType(Image()))
    _myTable.Columns.Add("No", GetType(Integer))
    _myTable.Columns.Add("Codeproduct", GetType(String))
    LoadData()
End Sub
Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
    If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Enter) Then
        Dim iRow As Integer
        If Grid.RowCount - 1 = 0 Then
            iRow = 1
        Else
            iRow = Convert.ToInt32(Grid.Rows(Grid.RowCount - 2).Cells(1).Value.ToString()) + 1
        End If
        FillDataTable(avatar, iRow, TextBox1.Text)
        Grid.DataSource = _myTable
        TextBox1.Clear()
    End If
End Sub
End Class
End Class
Public Class item
    Public Property No() As Integer
    Public Property CodeProduct() As String
    Public Function GetAvatar() As DataGridViewAvatar
        Return New DataGridViewAvatar() With {
        .Value = CType(Me.CodeProduct, String),
        .Icon = Image.FromFile("money.png")
    }
    End Function
End Class

DataGridView图片列显示效果


代码存在的问题

  1. 冗余无效代码:LoadData方法创建空列表且使用非标准绑定方法;item类定义后完全未使用,属于无用代码。
  2. 列配置错误:
    • AddColumnsProgrammatically中重复赋值Col2,覆盖初始设置,且图片列Col1未设置DataPropertyName,无法关联DataTable列。
    • DataTable图片列类型设为Image()(数组),但实际存储单个Image对象,类型不匹配。
  3. 行号计算风险:通过Grid.RowCount计算行号,当DataGridView允许添加新行时,Grid.RowCount - 2可能引发索引越界。
  4. 重复绑定数据源:每次回车都重新设置Grid.DataSource = _myTable,导致重复渲染,影响性能且可能重置列状态。
  5. 未定义变量:调用FillDataTable时使用的avatar变量未定义,会触发编译错误。

修正后的实现方案

修正步骤

  1. 清理无用的LoadData方法和item类。
  2. 修正DataTable图片列类型为Image(非数组)。
  3. 统一配置DataGridView列,确保DataPropertyName与DataTable列名一致。
  4. 从DataTable行数计算行号,避免索引越界。
  5. 仅初始化时绑定一次数据源,后续DataTable更新自动同步。
  6. 定义并初始化avatar变量(示例用本地图片路径)。

修正后的完整代码

' 类级别DataTable声明
Private _myTable As New DataTable()
' 示例图片变量,替换为实际路径
Private avatar As Image = Image.FromFile("money.png")

Private Sub AddColumnsProgrammatically()
    ' 图片列配置
    Dim imgCol = New DataGridViewImageColumn()
    imgCol.Name = "AvatarColumn"
    imgCol.HeaderText = ""
    imgCol.DataPropertyName = "Avatar" ' 与DataTable列名对应
    imgCol.ImageLayout = DataGridViewImageCellLayout.Zoom ' 优化图片显示

    ' 序号列
    Dim noCol = New DataGridViewTextBoxColumn()
    noCol.Name = "NoColumn"
    noCol.HeaderText = "No"
    noCol.DataPropertyName = "No"

    ' 产品编码列
    Dim codeCol = New DataGridViewTextBoxColumn()
    codeCol.Name = "CodeColumn"
    codeCol.HeaderText = "CodeProduct"
    codeCol.DataPropertyName = "Codeproduct"

    Grid.Columns.AddRange(New DataGridViewColumn() {imgCol, noCol, codeCol})
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ' 初始化DataTable列
    _myTable.Columns.Add("Avatar", GetType(Image))
    _myTable.Columns.Add("No", GetType(Integer))
    _myTable.Columns.Add("Codeproduct", GetType(String))

    ' 配置DataGridView列
    AddColumnsProgrammatically()

    ' 仅绑定一次数据源
    Grid.DataSource = _myTable
End Sub

Private Sub FillDataTable(Avatar As Image, iRow As Integer, ByVal Codeproduct As String)
    Dim row As DataRow = _myTable.NewRow()
    row("Avatar") = Avatar
    row("No") = iRow
    row("Codeproduct") = Codeproduct
    _myTable.Rows.Add(row)
End Sub

Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
    If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Enter) Then
        ' 从DataTable行数计算行号,避免索引越界
        Dim iRow As Integer = _myTable.Rows.Count + 1
        FillDataTable(avatar, iRow, TextBox1.Text)
        TextBox1.Clear()
    End If
End Sub
End Class

关键说明

  • 列绑定一致性:DataGridView列的DataPropertyName必须与DataTable列名完全匹配,才能自动关联数据。
  • 数据源优化:仅初始化时设置一次数据源,后续DataTable的增删改操作会自动同步到DataGridView,无需重复绑定。
  • 行号逻辑:使用_myTable.Rows.Count + 1计算下一行序号,不受DataGridView新行设置影响,逻辑更可靠。
  • 图片显示:设置ImageLayout = Zoom让图片按比例适配单元格,提升显示效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:44:55