I am using RowFilter to highlight rows in a datagridview, but when i clear the filter to view all records it removes the highlight i applied:
Sorter.DtSample.DefaultView.RowFilter = "FirstName = 'John'"
For Each R0w In Sorter.DataGridView1.Rows
R0w.defaultcellstyle.forecolor = Color.Red
Sorter.DataGridView1(0, R0w.index).Value = True
Next
Sorter.DtSample.DefaultView.RowFilter = ""
You can use CellFormatting
or RowPrepaint
evant to apply some formatting to rows. In this case it's enough to check the criteria for the row which the event if fired for it and apply the format to the row if required. (Thanks to Plutonix for mentioning RowPrePaint
which seems to be faster than cellFormatting
in this case.)
Since the event is raised just for visible rows, there would not be a performance issue even if you have too many rows. Anyway having a DataGridView
with too many rows is not a good idea and in such cases you should use a mechanism like virtualization or paging.
Example
Regardless of number of records, here is an example which I colorize rows which their FirstName
starts with the text you entered in TextBox1
if you press Button1
. If you enter empty string in TextBox1
and press Button1
all rows will be shown in black.
To make the example working you need to have a DataGridView1
, TextBox1
and Button1
on form.
Public Class Form1
Dim dt As DataTable
Dim filter As String = ""
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
dt = New DataTable
dt.Columns.Add("FirstName")
dt.Columns.Add("LastName")
dt.Rows.Add("John", "Doe")
dt.Rows.Add("John", "Smith")
dt.Rows.Add("Sara", "Allen")
Me.DataGridView1.DataSource = dt
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
filter = Me.TextBox1.Text
Me.DataGridView1.Invalidate()
End Sub
Private Sub DataGridView1_RowPrePaint(sender As Object, _
e As DataGridViewRowPrePaintEventArgs) Handles DataGridView1.RowPrePaint
If (e.RowIndex < 0 OrElse e.RowIndex = DataGridView1.NewRowIndex) Then Return
Dim row = DataGridView1.Rows(e.RowIndex)
If (String.IsNullOrEmpty(filter)) Then
row.DefaultCellStyle.ForeColor = Color.Black
Else
Dim data = DirectCast(DataGridView1.Rows(e.RowIndex).DataBoundItem, _
DataRowView).Row
If data.Field(Of String)("FirstName").ToLower() _
.StartsWith(filter.ToLower()) Then
row.DefaultCellStyle.ForeColor = Color.Red
Else
row.DefaultCellStyle.ForeColor = Color.Black
End If
End If
End Sub
End Class
Note
If you apply RowFilter
to the data table which you set as DataSource
of DataGridView
, it shows just filtered rows. So I didn't used it because you want to colorize filtered rows in red and others in black, so we need to show all rows.