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

如何为DataGridView行标题自动添加不同颜色图标?支持随机配色及多列关联

基于DataGridView列值自定义行标题图标与颜色方案

一、基于Column1值匹配固定颜色图标

原代码是按行索引循环颜色,要实现按Column1值对应固定颜色,我们可以用字典存储Column1值与颜色的映射关系,在CellPainting事件中根据当前行的Column1值获取对应颜色:

' 存储Column1值到颜色的映射
Private columnColorMap As New Dictionary(Of String, Color)

Protected Overrides Sub OnLoad(e As EventArgs)
    MyBase.OnLoad(e)

    ' 初始化Column1对应的固定颜色
    columnColorMap.Add("Item1", Color.Red)
    columnColorMap.Add("Item2", Color.Green)
    columnColorMap.Add("Item3", Color.Orange)
    columnColorMap.Add("Item4", Color.Black)

    Dim Table1 = New DataTable("TableName")
    Table1.Columns.AddRange({
        New DataColumn("Column1", GetType(String)),
        New DataColumn("Column2", GetType(Integer)),
        New DataColumn("Column3", GetType(Integer))
    })

    Table1.Rows.Add("Item1", 44, 99)
    Table1.Rows.Add("Item2", 50, 70)
    Table1.Rows.Add("Item3", 75, 85)
    Table1.Rows.Add("Item2", 60, 70)
    Table1.Rows.Add("Item3", 85, 85)
    Table1.Rows.Add("Item4", 77, 21)
    Table1.Rows.Add("Item2", 60, 70)

    DataGridView1.RowTemplate.Height = 48
    DataGridView1.RowHeadersWidth = 48
    DataGridView1.DataSource = Table1
End Sub

Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
    If e.RowIndex >= 0 AndAlso e.ColumnIndex = -1 AndAlso e.RowIndex <> DataGridView1.NewRowIndex Then
        Dim g = e.Graphics
        Dim sz = Math.Min(e.CellBounds.Width, e.CellBounds.Height) - 6
        Dim ellipseRect = New Rectangle(
            e.CellBounds.X + (e.CellBounds.Width - sz) \ 2,
            e.CellBounds.Y + (e.CellBounds.Height - sz) \ 2,
            sz, sz)
        Dim imgRect = Rectangle.Inflate(ellipseRect, -3, -3)

        ' 获取当前行的Column1值
        Dim column1Value = DataGridView1.Rows(e.RowIndex).Cells("Column1").Value.ToString()
        ' 从字典中获取对应颜色,无匹配项时默认用灰色
        Dim currentColor = If(columnColorMap.ContainsKey(column1Value), columnColorMap(column1Value), Color.Gray)

        ' 绘制单元格背景、边框等基础元素
        e.Paint(e.ClipBounds, DataGridViewPaintParts.Background Or DataGridViewPaintParts.Border Or DataGridViewPaintParts.SelectionBackground)

        ' 绘制带颜色的椭圆背景和图标
        Using bmp = My.Resources.SomeImage, ellipseBrush = New SolidBrush(currentColor)
            g.SmoothingMode = SmoothingMode.AntiAlias
            g.FillEllipse(ellipseBrush, ellipseRect)
            g.SmoothingMode = SmoothingMode.None
            g.DrawImage(bmp, imgRect, 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel)
        End Using

        e.Handled = True
    End If
End Sub

说明:用Dictionary存储对应关系,保证同一Column1值的行标题颜色完全统一,比原代码按行索引循环的方式更贴合需求。

二、基于Column1值自动生成随机颜色(同一值颜色一致)

如果不想手动设置颜色,可在第一次遇到某个Column1值时生成随机颜色并存入字典,后续复用该颜色:

' 存储Column1值到颜色的映射
Private columnColorMap As New Dictionary(Of String, Color)
' 随机颜色生成器
Private rand As New Random()

Protected Overrides Sub OnLoad(e As EventArgs)
    MyBase.OnLoad(e)
    ' 无需手动添加颜色,改为动态生成
    ' ... 表格初始化代码与上述一致 ...
End Sub

Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
    If e.RowIndex >= 0 AndAlso e.ColumnIndex = -1 AndAlso e.RowIndex <> DataGridView1.NewRowIndex Then
        ' ... 矩形、绘图对象初始化代码与上述一致 ...

        Dim column1Value = DataGridView1.Rows(e.RowIndex).Cells("Column1").Value.ToString()
        Dim currentColor As Color

        ' 字典无该值时生成随机颜色并存入
        If Not columnColorMap.ContainsKey(column1Value) Then
            ' 生成亮度适中的随机颜色,避免太暗/太亮导致图标看不清
            currentColor = Color.FromArgb(rand.Next(50, 200), rand.Next(50, 200), rand.Next(50, 200))
            columnColorMap.Add(column1Value, currentColor)
        Else
            currentColor = columnColorMap(column1Value)
        End If

        ' ... 后续绘制代码与上述一致 ...
    End If
End Sub

说明:通过Random生成RGB值在50-200之间的颜色,用字典缓存确保同一Column1值的行标题颜色始终相同。

三、结合Column1和Column2的值进行判断

若需同时依据两个列的值决定颜色,可直接在代码中添加判断逻辑:

Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
    If e.RowIndex >= 0 AndAlso e.ColumnIndex = -1 AndAlso e.RowIndex <> DataGridView1.NewRowIndex Then
        ' ... 前面的初始化代码 ...

        Dim column1Value = DataGridView1.Rows(e.RowIndex).Cells("Column1").Value.ToString()
        Dim column2Value = CInt(DataGridView1.Rows(e.RowIndex).Cells("Column2").Value)
        Dim currentColor As Color

        ' 结合Column1和Column2判断颜色
        Select Case column1Value
            Case "Item1"
                currentColor = Color.Red
            Case "Item2"
                ' Item2的情况下,Column2>55用深蓝色,否则用绿色
                currentColor = If(column2Value > 55, Color.DarkBlue, Color.Green)
            Case "Item3"
                ' Item3的情况下,Column2>=80用橙色,否则用黄色
                currentColor = If(column2Value >= 80, Color.Orange, Color.Yellow)
            Case Else
                currentColor = Color.Gray
        End Select

        ' ... 后续绘制代码 ...
    End If
End Sub

说明:通过Select Case结合双列值做精细化判断,你可根据实际需求调整判断条件和对应颜色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:19:56