【问题标题】:Highlight Part of a text in a cell of datagridview突出显示datagridview单元格中的部分文本
【发布时间】:2011-03-27 18:08:15
【问题描述】:

如何在 datagridview 的单元格中突出显示部分文本? 我正在使用 C#。
例如用户搜索书籍。一个单元格包含书签。我想在书签中突出显示“书”。 谢谢。


版。 这段代码可以吗?

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

【问题讨论】:

  • 部分是指插入文本的一部分、整个文本还是什么?
  • 部分文字。例如用户搜索的书。一个单元格包含书签。我想在书签中突出显示“书”。

标签: c# datagridview highlighting


【解决方案1】:

我也在寻找一种方法来做到这一点。转到明显的 CellPainting 事件后,我发现使用事件的 Graphics 对象并没有成功。但是,我确实设法使用 DataGridView.GetGraphics() 方法中的 Graphics 对象来突出显示部分文本。 我假设您已经知道如何找到包含您搜索的字符串的单元格。 在 CellPainting 事件中,您要做的第一件事就是将单元格绘制为任何其他单元格:

 e.Paint(e.ClipBounds, DataGridViewPaintParts.All);

接下来要做的是将单元格的文本分成两部分 - 搜索文本之前的部分和搜索文本本身。您需要它来计算要突出显示的矩形。

然后使用 Graphics 对象的 MeasureString 方法获取单元格内搜索文本的位置。由于我使用的是与网格本身相关的 Graphics 对象,而不是事件的 Graphics 对象,因此我必须计算网格内高亮矩形的位置。我已经使用DataGridView.GetCellDisplayRectangle 方法找到网格内单元格的位置,并添加了高亮矩形位置的这个位置:

 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);

从那时起,它只是使用 Graphics 对象的 FillRectangle 和 DrawString:

 g.FillRectangle(new SolidBrush(Color.Black), HighLightedRect);
 g.DrawString(HighlighetText, dgvGrid.Font, new SolidBrush(Color.White), HighLightedRect.Location);
 g.Flush();

当然,完成后不要忘记将 e 的 Handled 属性设置为 true:

e.Handled = true; 

哦,还有最后一件事:每次搜索新字符串时,您都需要使整个网格无效,或者至少使之前搜索中突出显示的单元格无效,否则最终会得到一个充满突出显示的网格与当前搜索字符串无关的文本。

【讨论】:

  • 能否请您展示此方法的工作示例?
  • @Sipo 哇。信不信由你,这是我在 stackoverflow 上回答的第一个问题。我当时确实有一个工作代码示例作为我当时工作的公司代码的一部分,但是由于我更换了雇主并且不再可以访问此代码。但是,我认为这个答案应该包含足够的代码来创建一个工作示例。
  • 感谢您的快速回答!我确实尝试重建您的解决方案,但是我无法弄清楚丢失的位太多。例如,您将CellRectangleHighLightedRectSizeBeforeHighLightHighLightedSize 等视为已经初始化。但我不确定如何初始化它们。另外,您建议使用MeasureString(),但我不确定如何使用,尤其是在我以前使用此方法的经验中,它并不准确。所以如果你能找到时间来改进这个答案,那就太好了!
  • 好吧,我不确定我是否有时间重新创建一个完整的示例,尤其是在周末之前。也许周六我会有一些时间,但我不能保证任何事情。
【解决方案2】:

我不认为有任何内置的方法,但我假设你可以处理DataGridViewCellPainting 事件,设置e.Handled = true;,然后根据需要自己绘制它.

您或许可以使用PaintBackground 来最大程度地减少您必须自己完成的工作量。

【讨论】:

    猜你喜欢
    • 2014-05-10
    • 2013-07-23
    • 2010-12-17
    • 2012-03-24
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多