DataGridView.Refresh 引发 System.NullReferenceException

DataGridView.Refresh throws System.NullReferenceException

提问人:Alan O'Brien 提问时间:10/4/2022 更新时间:10/4/2022 访问量:202

问:

我有一个带有许多“自定义”按钮列的按钮列。突然间,我注意到,当我为其中一个按钮(但不是其他任何按钮)操作代码时,当我尝试刷新 DGV 时,我得到了一个未经处理的异常。DataGridView

这是有问题的代码:

Private Sub editAction(clickedButton As DataGridViewCustomButtonCell)
    Try
        Dim activeRow As DataGridViewRow = dgv.Rows(clickedButton.RowIndex)
        Select Case clickedButton.Value
            Case True
                ' Entering Edit mode
                activeRow.Cells(statusColumn.Index).Value = "Editing"

            Case False
                ' Exiting Edit mode
                If activeRow.Cells(idColumn.Index).Value = -1 Then
                    activeRow.Cells(statusColumn.Index).Value = "Copy"
                ElseIf activeRow.Cells(idColumn.Index).Value = -2 Then
                    activeRow.Cells(statusColumn.Index).Value = "New"
                Else
                    activeRow.Cells(statusColumn.Index).Value = ""
                End If

        End Select
        dgv.Refresh()

    Catch ex As Exception

    End Try
End Sub

这是例外:

System.NullReferenceException:'对象引用未设置为 对象的实例'

几天前这工作正常,当突然出现这个异常时,我正在做其他事情,但我不知道我可能改变了什么来突然导致它?就像我说的,其他按钮工作正常,当代码完成时,它们都会触发相同的方法。所以不确定为什么这个特定的突然成为一个问题?.Refresh

每个手表的子中没有一个变量是空的,DGV 本身也是如此。而且这个例外并没有给我太多细节,说明它到底是什么可能是空的,以至于它导致了问题?

(没有,但这是如果它有任何用处 - 对我来说没有意义)InnerExceptionStackTrace

在 System.Windows.Forms.DataGridViewTextBoxCell.PaintPrivate(图形 图形、矩形 clipBounds、矩形 cellBounds、 Int32 rowIndex、 DataGridViewElementStates cellState、Object formattedValue、String errorText、DataGridViewCellStyle cellStyle、 DataGridViewAdvancedBorderStyle 高级dBorderStyle, DataGridViewPaintParts paintParts、布尔值 computeContentBounds、 布尔值 computeErrorIconBounds, Boolean paint) 在 System.Windows.Forms.DataGridViewTextBoxCell.Paint(图形图形, 矩形 clipBounds、矩形 cellBounds、 Int32 rowIndex、 DataGridViewElementStates cellState, 对象值, 对象 formattedValue、字符串 errorText、DataGridViewCellStyle cellStyle、 DataGridViewAdvancedBorderStyle 高级dBorderStyle, DataGridViewPaintParts paintParts) 在 System.Windows.Forms.DataGridViewCell.PaintWork(图形图形, 矩形 clipBounds、矩形 cellBounds、 Int32 rowIndex、 DataGridViewElementStates、cellState、DataGridViewCellStyle、 DataGridViewAdvancedBorderStyle 高级dBorderStyle, DataGridViewPaintParts paintParts) 在 System.Windows.Forms.DataGridViewRow.PaintCells (图形图形, 矩形 clipBounds、矩形 rowBounds、 Int32 rowIndex、 DataGridViewElementStates rowState,布尔值 isFirstDisplayedRow, 布尔值 isLastVisibleRow, DataGridViewPaintParts paintParts) 在 System.Windows.Forms.DataGridViewRow.Paint (图形图形, 矩形 clipBounds、矩形 rowBounds、 Int32 rowIndex、 DataGridViewElementStates rowState,布尔值 isFirstDisplayedRow, 布尔值 isLastVisibleRow) 在 System.Windows.Forms.DataGridView.PaintRows(图形 g,矩形 boundingRect、Rectangle clipRect、Boolean singleHorizontalBorderAdded) 在 System.Windows.Forms.DataGridView.PaintGrid (图形 g,矩形 gridBounds、矩形、clipRect、布尔值、singleVerticalBorderAdded、 布尔值 singleHorizontalBorderAdded) 在 System.Windows.Forms.DataGridView.OnPaint (PaintEventArgs e) 位于 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 层) 在 System.Windows.Forms.Control.WmPaint(Message& m) 在 System.Windows.Forms.Control.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 消息、IntPtr wparam、IntPtr lparam)

我唯一能想到的是自定义按钮单元格类正在翻倒,但这段代码始终保持不变,所以我不知道为什么它会突然成为一个问题?Protected Overrides Sub Paint

Public Class DataGridViewCustomButtonCell
    Inherits DataGridViewButtonCell

    Public Overrides Function Clone() As Object
        Dim cell As DataGridViewCustomButtonCell = CType(MyBase.Clone(), DataGridViewCustomButtonCell)
        cell.IsEnabled = Me.IsEnabled
        Return cell
    End Function

    Public Sub New()
        Me.isEnabledValue = True
    End Sub

    Protected Overrides Sub Paint(ByVal graphics As Graphics,
        ByVal clipBounds As Rectangle, ByVal cellBounds As Rectangle,
        ByVal rowIndex As Integer,
        ByVal elementState As DataGridViewElementStates,
        ByVal value As Object, ByVal formattedValue As Object,
        ByVal errorText As String,
        ByVal cellStyle As DataGridViewCellStyle,
        ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle,
        ByVal paintParts As DataGridViewPaintParts)

        ' Draw the background of the cell, if specified.
        If (paintParts And DataGridViewPaintParts.Background) = DataGridViewPaintParts.Background Then
            Dim cellBackground As New SolidBrush(IIf(Me.isToggleValue AndAlso Me.isPressedValue, Color.Black, cellStyle.BackColor))
            graphics.FillRectangle(cellBackground, cellBounds)
            cellBackground.Dispose()
        End If

        ' Draw the cell borders, if specified.
        If (paintParts And DataGridViewPaintParts.Border) = DataGridViewPaintParts.Border Then
            PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle)
        End If

        ' Calculate the area in which to draw the button.
        Dim buttonArea As Rectangle = cellBounds
        Dim buttonAdjustment As Rectangle = Me.BorderWidths(advancedBorderStyle)
        buttonArea.X += buttonAdjustment.X
        buttonArea.Y += buttonAdjustment.Y
        buttonArea.Height -= buttonAdjustment.Height
        buttonArea.Width -= buttonAdjustment.Width

        ' Calculate the area in which to draw the image.
        Dim imagearea As Rectangle = New Rectangle(buttonArea.X + 5, buttonArea.Y + 5, buttonArea.Width - 10, buttonArea.Height - 10)

        ' Draw the button
        If enabledImage Is Nothing Then enabledImage = buttonImagesEnabled(Me.OwningColumn.Index)
        If disabledImage Is Nothing Then disabledImage = buttonImagesDisabled(Me.OwningColumn.Index)

        If enabledImage IsNot Nothing AndAlso disabledImage IsNot Nothing Then
            ButtonRenderer.DrawButton(graphics, buttonArea, IIf(Me.isEnabledValue, enabledImage, disabledImage), imagearea, False, IIf(Me.isEnabledValue, IIf(Me.isPressedValue, PushButtonState.Pressed, PushButtonState.Normal), PushButtonState.Disabled))
        Else
            ButtonRenderer.DrawButton(graphics, buttonArea, IIf(Me.isEnabledValue, IIf(Me.isPressedValue, PushButtonState.Pressed, PushButtonState.Normal), PushButtonState.Disabled))
        End If

        Me.ToolTipText = ""

    End Sub

End Class

任何建议将不胜感激!

vb.net DataGridView NullReferenceException

评论

0赞 Hursey 10/4/2022
顺便说一句,可能会花钱审查您对 dgv 的使用情况。刷新()。这不会像我怀疑您可能期望的那样刷新数据。这会强制重新绘制控件,这将导致 Paint 事件在可能不需要时触发
0赞 Alan O'Brien 10/4/2022
谢谢@Hursey - 不,我不希望它刷新数据,只是触发 .CellFormatting 事件,我有代码根据各种标准设置网格格式。有效的观点,谢谢,但不是这种特定情况下的问题......
0赞 Alan O'Brien 10/4/2022
啊 - 经过数小时的逐行调试后弄清楚了......根据之前的评论,我正在强制触发事件。在这段代码中,我(出于大约两天前只有我自己知道的原因)调用了一个单独的函数,该函数通过处置和重新创建来修改其中一个单元,从而创建空引用。我不应该在那里,我基本上是站在椅子上画椅子的。愚蠢的错误,函数调用已被适当地移动到它应该在的位置,我因为愚蠢而给了自己众所周知的打击,对不起.CellFormatting
0赞 Hursey 10/5/2022
很高兴听到你已经解决了。也许您可以将您的解决方案发布为可接受的答案?
0赞 Alan O'Brien 10/5/2022
我认为我创建的问题(即在事件期间处理网格元素并用定制元素替换它)可能非常小众?此外,问题不在于我发布的任何代码;它位于由调用触发的事件处理程序中。我想,如果其他人遇到这种问题,这里的评论足以帮助他们检查随后的事件 - 我的特定代码不一定相关?.CellFormatting.CellFormatting.Refresh.Refresh

答: 暂无答案