VB.NET中如何为DataGridView行标题添加不同颜色的透明图标
VB.NET DataGridView行标题图标每行不同颜色实现方案
要实现每行标题的透明PNG图标颜色不同,核心是给原始图标动态生成对应颜色的版本,再在行标题绘制时加载使用。下面提供两种可行方案:
方案一:动态着色PNG图标(推荐)
通过颜色矩阵给原始透明PNG图标着色,完整保留Alpha通道,适合各种类型的透明图标。
1. 图标着色工具函数
Private Function ColorizeIcon(originalIcon As Bitmap, targetColor As Color) As Bitmap Dim coloredBitmap As New Bitmap(originalIcon.Width, originalIcon.Height) Using g As Graphics = Graphics.FromImage(coloredBitmap) ' 构建颜色矩阵,对RGB通道应用目标颜色比例,保留透明度 Dim colorMatrix As New ColorMatrix(New Single()() { New Single() {targetColor.R / 255.0F, 0, 0, 0, 0}, New Single() {0, targetColor.G / 255.0F, 0, 0, 0}, New Single() {0, 0, targetColor.B / 255.0F, 0, 0}, New Single() {0, 0, 0, 1, 0}, New Single() {0, 0, 0, 0, 1} }) Using imageAttr As New ImageAttributes() imageAttr.SetColorMatrix(colorMatrix) g.DrawImage(originalIcon, New Rectangle(0, 0, originalIcon.Width, originalIcon.Height), 0, 0, originalIcon.Width, originalIcon.Height, GraphicsUnit.Pixel, imageAttr) End Using End Using Return coloredBitmap End Function
2. 行标题绘制事件处理
在RowPostPaint事件中,根据行索引或绑定数据确定颜色,生成对应图标并绘制:
Private Sub DataGridView1_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint ' 加载原始透明图标(替换为你的资源路径/资源文件) Dim originalIcon As New Bitmap(My.Resources.YourOriginalIcon) Dim rowIndex As Integer = e.RowIndex ' 自定义每行颜色逻辑:示例用循环颜色,可替换为绑定数据的颜色值 Dim rowColors As Color() = {Color.Red, Color.Green, Color.Blue, Color.Orange, Color.Purple} Dim targetColor As Color = rowColors(rowIndex Mod rowColors.Length) ' 生成对应颜色的图标 Dim coloredIcon As Bitmap = ColorizeIcon(originalIcon, targetColor) ' 计算居中绘制的位置 Dim headerRect As Rectangle = DataGridView1.RowHeadersRectangle(e.RowIndex) Dim drawX As Integer = headerRect.X + (headerRect.Width - coloredIcon.Width) \ 2 Dim drawY As Integer = headerRect.Y + (headerRect.Height - coloredIcon.Height) \ 2 ' 绘制着色后的图标 e.Graphics.DrawImage(coloredIcon, drawX, drawY) ' 释放资源,避免内存泄漏 coloredIcon.Dispose() End Sub
方案二:绘制叠加色(适合轮廓类透明图标)
如果你的图标是仅含黑色轮廓的透明图,可以直接绘制原始图标后,用目标颜色叠加填充非透明区域:
Private Sub DataGridView1_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint Dim originalIcon As New Bitmap(My.Resources.YourOutlineIcon) Dim rowIndex As Integer = e.RowIndex Dim rowColors As Color() = {Color.Red, Color.Green, Color.Blue, Color.Orange} Dim targetColor As Color = rowColors(rowIndex Mod rowColors.Length) Dim headerRect As Rectangle = DataGridView1.RowHeadersRectangle(e.RowIndex) Dim drawX As Integer = headerRect.X + (headerRect.Width - originalIcon.Width) \ 2 Dim drawY As Integer = headerRect.Y + (headerRect.Height - originalIcon.Height) \ 2 ' 先绘制原始图标,再用颜色叠加填充轮廓 Using brush As New SolidBrush(targetColor) e.Graphics.DrawImage(originalIcon, drawX, drawY) ' 设置混合模式,仅填充图标非透明区域 e.Graphics.CompositingMode = Drawing2D.CompositingMode.SourceAtop e.Graphics.FillRectangle(brush, drawX, drawY, originalIcon.Width, originalIcon.Height) ' 恢复默认混合模式 e.Graphics.CompositingMode = Drawing2D.CompositingMode.SourceOver End Using End Sub
额外说明
行标题背景色自定义:如果需要给行标题本身设置不同颜色,可在绘制图标前先填充背景:
e.Graphics.FillRectangle(New SolidBrush(Color.LightBlue), headerRect)或直接设置单元格样式:
DataGridView1.Rows(rowIndex).HeaderCell.Style.BackColor = targetColor性能优化:如果行数较多,建议缓存已着色的图标(比如用Dictionary存储颜色对应的图标),避免每次绘制都重新生成。
内容的提问来源于stack exchange,提问作者roy
相关产品推荐
相关产品推荐

