如何解决' GDI +中出现的一般错误'

时间:2014-08-28 20:06:10

标签: vb.net winforms datagridview gdi+

目标

能够在我的DataGridViews中绘制行,以帮助用户更好地了解应用程序中发生的事情。以此图片为例:

  • 浅红=已删除
  • 黄色=与选项类型的关系选择(左上角)
  • 鲜红色=已删除&与选择的选项类型相关(左上角)

Color Chart


问题

当我在Option Types DataGridView中上下移动时,它将根据我选择的选项类型绘制Mandatory和Additional部分。这样做了一段时间(70次左右)后,我在GDI中得到了一般错误。

正如您在上面的屏幕截图中看到的,其中一个附加编辑按钮未正确显示(这是发生错误的位置)。它始终位于以下行:

ico = Icon.FromHandle(bmpFind.GetHicon)

请参阅以下完整代码:

代码

Private Sub dgvAdditionalOptions_CellPainting(sender As Object, e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles dgvAdditionalOptions.CellPainting
    'Dim bmpFind As Bitmap
    Dim drRow As HunterManagement.dtConveyorFunctionAdditionalOptionsRow
    Dim myOptn As clsOptions

    If dgvAdditionalOptions.Columns(e.ColumnIndex).Name = "ColBtnEditAdditional" AndAlso e.RowIndex >= 0 Then
        drRow = dsHunterManagement.dtConveyorFunctionAdditionalOptions.FindByPK_ConveyorFunctionAdditionalOption(dgvAdditionalOptions.Rows(e.RowIndex).Cells("PK_ConveyorFunctionAdditionalOption").Value)
        myOptn = New clsOptions(CInt(drRow.FK_Option))
        e.Paint(e.CellBounds, DataGridViewPaintParts.All)

        If Not drRow Is Nothing AndAlso myOptn.InDrawing Then
            Using bmpFind As Bitmap = My.Resources.Edit_16x16_2 'Use 16x16 PNG / BitMap images
                Using ico As Icon = Icon.FromHandle(bmpFind.GetHicon)
                    e.Graphics.DrawIcon(ico, e.CellBounds.Left + 3, e.CellBounds.Top + 2.5)
                    e.Handled = True
                End Using
            End Using
        Else
            Using bmpFind As Bitmap = My.Resources.Edit_Disabled_16x16_2 'Use 16x16 PNG / BitMap images
                Using ico As Icon = Icon.FromHandle(bmpFind.GetHicon)
                    e.Graphics.DrawIcon(ico, e.CellBounds.Left + 3, e.CellBounds.Top + 2.5)
                    e.Handled = True
                End Using
            End Using
        End If
    ElseIf dgvAdditionalOptions.Columns(e.ColumnIndex).Name = "ColBtnDeleteAdditional" AndAlso e.RowIndex >= 0 Then
        e.Paint(e.CellBounds, DataGridViewPaintParts.All)
        Using bmpFind As Bitmap = My.Resources.Delete_16x16 'Use 16x16 PNG / BitMap images
            Using ico As Icon = Icon.FromHandle(bmpFind.GetHicon)
                e.Graphics.DrawIcon(ico, e.CellBounds.Left + 2, e.CellBounds.Top + 2.5)
                e.Handled = True
            End Using
        End Using
    End If
End Sub

我尝试搜索这个问题并且它都与“保存”图像有关...虽然我没有保存图像,但我只获得了BMP图像的图标。我必须忘记处理某些事情。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

通常这个错误导致我的gdi +泄漏。您需要Dispose Icon这是一个gdi +资源。完成后再添加ico.Dispose

使用Icon.FromHandle时,您需要通过DestroyIcon API手动清理它。

  

使用此方法时,必须使用处理生成的图标   Win32 API中的DestroyIcon方法,以确保资源   释放。

参考this answer,Hans为此问题提供了解决方法。

另请注意,当您从Dispose获取Bitmap时,您必须Resources.YourBitmap Resources.YourBitmap,因为Bitmap每次调用时基本上都会创建一个新的位图。 Dispose也是一个gdi +资源,你也应该处理它。

正如@Hanspassant在评论中指出的那样,Using语句更倾向于{{1}}资源。它们提供了一种方便可靠的处理资源的方式。