Highlight Part of a text in a cell of datagridview
How can i Highlight Part of a text in a cell of datagridview ? I am using C#.
For example user searches book. on of cells contains bookmark. I want to highlight "book" in bookmark. Thanks.Edition. Is this code ok?
Private Sub DataGridView1_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
If e.RowIndex >= 0 And e.ColumnIndex >= 0 Then
e.Handled = True
e.PaintBackground(e.CellBounds, True)
Dim sw As String = GetSearchWord(e.ColumnIndex)
If Not String.IsNullOrEmpty(sw) Then
Dim val As String = DirectCast(e.FormattedValue, String)
Dim sindx As Integer = val.ToLower.IndexOf(sw.ToLower)
If sindx >= 0 Then
'the highlite rectangle
Dim hl_rect As New Rectangle()
hl_rect.Y = e.CellBounds.Y + 2
hl_rect.Height = e.CellBounds.Height - 5
'find the size of the text before the search word
'and the size of the search word
Dim sBefore As String = val.Substring(0, sindx)
Dim sWord As String = val.Substring(sindx, sw.Length)
Dim s1 As Size = TextRenderer.MeasureText(e.Graphics, sBefore, e.CellStyle.Font, e.CellBounds.Size)
Dim s2 As Size = TextRenderer.MeasureText(e.Graphics, sWord, e.CellStyle.Font, e.CellBounds.Size)
开发者_开发百科 'adjust the widths to make the highlite more accurate
If s1.Width > 5 Then
hl_rect.X = e.CellBounds.X + s1.Width - 5
hl_rect.Width = s2.Width - 6
Else
hl_rect.X = e.CellBounds.X + 2
hl_rect.Width = s2.Width - 6
End If
'use darker highlight when the row is selected
Dim hl_brush As SolidBrush
If ((e.State And DataGridViewElementStates.Selected) <> DataGridViewElementStates.None) Then
hl_brush = New SolidBrush(Color.DarkGoldenrod)
Else
hl_brush = New SolidBrush(Color.LightGoldenrodYellow)
End If
'paint the background behind the search word
e.Graphics.FillRectangle(hl_brush, hl_rect)
hl_brush.Dispose()
End If
End If
'paint the content as usual
e.PaintContent(e.CellBounds)
End If
End Sub
I too was searching for a way to do that. After going to the obvious CellPainting event I've found that using the event's Graphics object did not do the trick. However, I did manage to use the Graphics object from the DataGridView.GetGraphics() method to do highlight a part of the text. I assume you already know how to find the cell that contains the string you search. inside the CellPainting event the first thing you want to do is paint the cell as any other cell:
e.Paint(e.ClipBounds, DataGridViewPaintParts.All);
The next thing to do is to split the cell's text to 2 parts - the part before the search text and the search text itself. you need this in order to calculate the rectangle where you want to highlight.
Then use the MeasureString method of the Graphics object to get the location of the search text within the cell. Since I'm using the Graphics object related to the grid itself, and not the Graphics object of the event, I had to calculate the location of the highlight rectangle within the grid. I've used the DataGridView.GetCellDisplayRectangle method to find the location of the cell inside the grid, and added this location of the highlight rectangle location:
CellRectangle = Cell.DataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
HighLightedRect = new Rectangle((Point)SizeBeforeHighLight, HighLightedSize);
HighLightedRect.Location = new Point(CellRectangle.Location.X + SizeBeforeHighLight.Width, CellRectangle.Location.Y + Cell.ContentBounds.Top);
From that point on it's simply using the FillRectangle and DrawString of the Graphics object:
g.FillRectangle(new SolidBrush(Color.Black), HighLightedRect);
g.DrawString(HighlighetText, dgvGrid.Font, new SolidBrush(Color.White), HighLightedRect.Location);
g.Flush();
and of course, don't forget to set the Handled property of e to true when done:
e.Handled = true;
Oh, and one last thing: You will need to invalidate the entire grid, or at least the cells that was highlighted in the previous search every time you search a new string, otherwise you will end up with a grid full of highlighted text that has nothing to do with the current search string.
I don't think there's any built in way of doing it, but I'd assume that you could handle the CellPainting
event of the DataGridView
, set e.Handled = true;
and then draw it yourself as you need it.
You might be able to use PaintBackground
to minimize the amount of work you have to do yourself.
精彩评论