WinForm DataGrid根据指定列值设置整行背景色
Got it, since you're working with the classic WinForms DataGrid (not the more modern DataGridView), there's no out-of-the-box event for conditional row styling. But we can build this functionality by creating a custom DataGridTableStyle and overriding its row-drawing logic. Let's break this down:
Step 1: Create a Custom DataGridTableStyle
First, we'll make a subclass of DataGridTableStyle that checks the "Act" column value before drawing each row. This lets us change the background color only when the value is "12":
Imports System.Windows.Forms Imports System.Drawing Public Class CustomChannelTableStyle Inherits DataGridTableStyle Protected Overrides Sub DrawRow(g As Graphics, bounds As Rectangle, rowNum As Integer) ' Grab the data row for the current grid row Dim rowView As DataRowView = CType(Me.DataGrid.Item(rowNum).List, DataView)(rowNum) Dim actValue As String = rowView("Act").ToString() ' Save the original row background color to restore later Dim originalColor As Color = Me.RowBackColor ' Switch to our highlight color if Act equals "12" If actValue = "12" Then Me.RowBackColor = Color.LightCoral ' Pick any color you want here End If ' Let the base class draw the row with our updated color MyBase.DrawRow(g, bounds, rowNum) ' Put the original color back so other rows don't inherit the highlight Me.RowBackColor = originalColor End Sub End Class
Step 2: Replace Your Existing TableStyle with the Custom One
Now swap out your original DataGridTableStyle instance with this custom version. Make sure the MappingName matches your DataTable's name ("Channels")—this is critical for the style to apply correctly:
' Replace your original Dim ts As New DataGridTableStyle with this Dim ts As New CustomChannelTableStyle ts.MappingName = "Channels" ' Must match your DataTable's name exactly! ' Keep your existing Act column configuration Dim ActCol As New DataGridTextBoxColumn ActCol.MappingName = "Act" ActCol.Alignment = HorizontalAlignment.Center ActCol.HeaderText = "Action" ts.GridColumnStyles.Add(ActCol) ' Clear any existing styles first to avoid conflicts StatusTable.TableStyles.Clear() StatusTable.TableStyles.Add(ts) ' Re-bind your data if needed (or keep your existing binding) StatusTable.DataSource = StatusDS.Tables("Channels")
Key Things to Keep in Mind
- Matching MappingName: If your custom table style's
MappingNamedoesn't exactly match your DataTable's name ("Channels"), the style won't apply—this is a super common gotcha with the old DataGrid. - Row Indexes: The
rowNumparameter inDrawRowstarts at 0, so your 2nd and 5th rows (1-indexed) will be rowNum 1 and 4, which the code handles correctly. - Color Cleanup: Restoring the original background color after drawing is important—otherwise, every row after a highlighted one will keep the highlight color.
- Performance Tip: If you're working with a huge dataset, cache the indexes of rows where "Act" is "12" (maybe in a
List(Of Integer)) so you don't have to fetch the DataRowView every time the grid redraws.
Alternative: Using the DataGrid's Paint Event
If you don't want to create a custom table style, you can handle the DataGrid's Paint event directly. This is a bit less clean because you have to handle row scrolling and redrawing content, but it works:
Private Sub StatusTable_Paint(sender As Object, e As PaintEventArgs) Handles StatusTable.Paint Dim grid As DataGrid = CType(sender, DataGrid) Dim tableStyle As DataGridTableStyle = grid.TableStyles("Channels") For rowNum As Integer = 0 To grid.VisibleRowCount - 1 Dim rowView As DataRowView = CType(grid.Item(rowNum).List, DataView)(rowNum) If rowView("Act").ToString() = "12" Then Dim rowBounds As Rectangle = grid.GetCurrentRowBounds(rowNum) ' Draw the highlight background e.Graphics.FillRectangle(New SolidBrush(Color.LightCoral), rowBounds) ' Redraw the row content so it doesn't get covered by the background tableStyle.DrawRow(e.Graphics, rowBounds, rowNum) End If Next End Sub
That said, the custom table style method is more robust and easier to maintain long-term.
内容的提问来源于stack exchange,提问作者hedbisker

