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

DataGridView自定义ColorPickerCell返回Nothing问题求助

问题解决:DataGridView自定义ColorPickerCell获取失败的修复

核心原因

你当前的ColorColumn是普通的DataGridViewButtonColumn,未将其CellTemplate设置为自定义的ColorPickerCell,导致点击时获取到的单元格实际是DataGridViewButtonCell,TryCast自然返回Nothing。

修复步骤

1. 创建自定义列类(推荐)

新增继承自DataGridViewButtonColumn的ColorPickerColumn类,确保列的单元格模板绑定到你的ColorPickerCell:

Public Class ColorPickerColumn
    Inherits DataGridViewButtonColumn
    Public Sub New()
        MyBase.New()
        Me.CellTemplate = New ColorPickerCell()
    End Sub
End Class

2. 替换DataGridView中的列类型

  • 设计时添加列:将ColorColumn的类型从DataGridViewButtonColumn改为ColorPickerColumn
  • 代码创建列:用ColorPickerColumn替代DataGridViewButtonColumn来创建ColorColumn

3. 调整事件处理代码

修改事件中的类型判断逻辑,直接检查单元格是否为ColorPickerCell,简化获取逻辑:

Private Sub dgvDMs_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvDMs.CellContentClick
    If e.RowIndex < 0 Then Return
    
    Dim currentCell = TryCast(dgvDMs.Rows(e.RowIndex).Cells(e.ColumnIndex), ColorPickerCell)
    If currentCell IsNot Nothing AndAlso dgvDMs.Columns(e.ColumnIndex).Name = "ColorColumn" Then
        Using dlg As New ColorDialog()
            If dlg.ShowDialog() = DialogResult.OK Then
                currentCell.Color = dlg.Color
                dgvDMs.InvalidateCell(e.ColumnIndex, e.RowIndex)
            End If
        End Using
    End If
End Sub

4. 优化ColorPickerCell的Paint方法(可选)

避免formattedValue为空时的异常,添加空值判断:

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

    MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value,
    formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)

    Using darkPen As New Pen(SystemColors.ControlDark)
        Dim rc As New Rectangle(cellBounds.X + 8, cellBounds.Y + 3,
            cellBounds.Width - CInt(cellBounds.Width * phi / 8),
            cellBounds.Height - CInt(cellBounds.Height * phi / 4))
        
        Dim drawColor As Color = Color.White ' 默认白色
        If formattedValue IsNot Nothing AndAlso Integer.TryParse(formattedValue.ToString(), Nothing) Then
            drawColor = Color.FromArgb(Integer.Parse(formattedValue.ToString()))
        End If
        
        graphics.FillRectangle(New SolidBrush(drawColor), rc)
        graphics.DrawRectangle(darkPen, rc)
    End Using
End Sub

关键说明

  • 必须确保列的CellTemplate指向自定义单元格类,否则DataGridView会默认创建基础类型的单元格
  • 使用Using语句管理ColorDialog和绘图资源,避免内存泄漏
  • 调用InvalidateCell而非Me.Invalidate(),只刷新目标单元格,提升性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:15:59