图片未显示在 vb.net 的 datagridview 列中

Image not displaying in datagridview column in vb.net

我想使用以下代码在 DataGridView 单元格中显示图像:

dgvInventory.Item(7, i).Value = My.Resources.ResourceManager.GetObject("picture")

但它没有显示所需的图像,而是在单元格中显示 System.Drawing.Bitmap

请注意 DataGridView table 是在 运行 时间创建的,所以我知道我应该将列 属性 更改为 DataGridViewImageColumn 但我就是不知道怎么办。

提前致谢

拜托,我真的需要帮助。

完整代码如下

con.Open()
tables.Clear()
dgvInventory.DataSource = tables
dgvInventory.DataSource = Nothing

sql = "SELECT ItemID, itemname, status, ''  FROM [" & InventoryTable & "]"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, InventoryTable)
con.Close() 

'This Loads Records into DataGrid
Dim view As New DataView(tables(0))
source1.DataSource = view
dgvInventory.DataSource = view
dgvInventory.AllowUserToAddRows = False

For i = 0 To dgvInventory.RowCount - 1
   If dgvInventory.Item(2, i).Value = 1 then
     dgvInventory.Item(3, i).Value = My.Resources.ResourceManager.GetObject("picture")
   Else
     dgvInventory.Item(3, i).Value = My.Resources.ResourceManager.GetObject("picture1")
   End If
Next

dgvInventory.Columns(0).HeaderText = "ID"
dgvInventory.Columns(1).HeaderText = "Item / Product / Service"
dgvInventory.Columns(2).HeaderText = "Status"
dgvInventory.Columns(3).HeaderText = "Icon"

dgvInventory.Columns(0).Width = 100
dgvInventory.Columns(1).Width = 300
dgvInventory.Columns(2).Width = 100
dgvInventory.Columns(3).Width = 100

dgvInventory.ClearSelection()

如果你得到类似的东西:

那是因为您得到 ToString 函数 returns 的 Bitmap 类型的实例显示在默认 DataGridViewTextBoxCell 中。请注意,图标 不是您的 DataTable 的一部分,它只是您资源中的一个图像。

相反,在设置 DGV 的 DataSource 属性 之后添加一个新的 DataGridViewImageColumn。请考虑以下示例:

'Class level variables
Private bmp1 As New Bitmap(My.Resources.picture)
Private bmp2 As New Bitmap(My.Resources.picture1)

在调用和显示数据的方法中将其替换为您的实际数据源。

Dim dt As New DataTable
dt.Columns.Add(New DataColumn("ID"))
dt.Columns.Add(New DataColumn("Item"))
dt.Columns.Add(New DataColumn("Status"))

For i As Integer = 1 To 10
    dt.Rows.Add(i, $"Item {i}", $"Status {i}")
Next

With dgvInventory
    .Clear()
    .DataSource = Nothing
    .DataSource = dt
    .Columns("Item").HeaderText = "Item / Product / Service"
End With

Dim imageColIndex As Integer = dgvInventory.Columns.Count
Dim imgCol As New DataGridViewImageColumn(False) With {
    .CellTemplate = New DataGridViewImageCell() With {
        .Style = New DataGridViewCellStyle() With {
            .Alignment = DataGridViewContentAlignment.MiddleCenter
        }
    },
    .DisplayIndex = imageColIndex,
    .Image = Nothing,
    .Name = "Image",
    .HeaderText = "Image",
    .Width = CInt(dgvInventory.RowTemplate.Height * 1.5),
    .DefaultCellStyle = New DataGridViewCellStyle() With {.NullValue = Nothing}
}

AddHandler dgvInventory.CellFormatting,
    Sub(obj, arg)
        If arg.ColumnIndex = imageColIndex Then
            arg.Value = If(arg.RowIndex Mod 2 = 0, bmp1, bmp2)
        End If
    End Sub

dgvInventory.Columns.Insert(imageColIndex, imgCol)

其中 imageColIndex 是图像列的索引。

不要忘记在From.Closing事件中清理:

bmp1?.Dispose()
bmp2?.Dispose()

你会得到类似的东西:

请注意,您不需要在设计时添加列,您可以在绑定 DataTableDataViewBindingSource、..etc 后编辑列属性.到你的 DGV。

在您的代码中实现:

tables.Clear()
con.Open()
sql = "SELECT ItemID, itemname, status, ''  FROM [" & InventoryTable & "]"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, InventoryTable)
con.Close()
con.Dispose()

Dim view As New DataView(tables(0))
source1.DataSource = view

With dgvInventory
    .Columns.Clear()
    .DataSource = Nothing
    .DataSource = view
    .Columns(0).HeaderText = "ID"
    .Columns(0).Width = 100
    .Columns(1).HeaderText = "Item / Product / Service"
    .Columns(1).Width = 300
    .Columns(2).HeaderText = "Status"
    .Columns(2).Width = 100
End With

Dim imageColIndex As Integer = dgvInventory.Columns.Count
Dim imgCol As New DataGridViewImageColumn(False) With {
    .CellTemplate = New DataGridViewImageCell() With {
    .Style = New DataGridViewCellStyle() With {
    .Alignment = DataGridViewContentAlignment.MiddleCenter
}
},
.DisplayIndex = imageColIndex,
.Image = Nothing,
.Name = "Icon",
.HeaderText = "Icon",
.Width = CInt(dgvInventory.RowTemplate.Height * 1.5),
.DefaultCellStyle = New DataGridViewCellStyle() With {.NullValue = Nothing}
}

AddHandler dgvInventory.CellFormatting,
    Sub(obj, arg)
        If arg.ColumnIndex = imageColIndex Then
            Dim status As Integer = Convert.ToInt32(
            DirectCast(obj, DataGridView).Item(2, arg.RowIndex).Value)

            arg.Value = If(status = 1, bmp1, bmp2)
        End If
    End Sub

dgvInventory.Columns.Insert(imageColIndex, imgCol)
dgvInventory.ClearSelection()