Выделить часть текста в ячейке просмотра данных - PullRequest
3 голосов
/ 10 августа 2010

Как выделить часть текста в ячейке таблицы данных? Я использую 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

Ответы [ 2 ]

3 голосов
/ 12 января 2014

Я тоже искал способ сделать это. Перейдя к очевидному событию CellPainting, я обнаружил, что использование объекта Graphics объекта не помогло. Однако мне удалось использовать объект Graphics из метода DataGridView.GetGraphics (), чтобы выделить часть текста. Я предполагаю, что вы уже знаете, как найти ячейку, содержащую строку, которую вы ищете. внутри события CellPainting первое, что вы хотите сделать, это нарисовать ячейку как любую другую ячейку:

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

Следующее, что нужно сделать, это разделить текст ячейки на 2 части - часть перед текстом поиска и сам текст поиска. это нужно для вычисления прямоугольника, в котором вы хотите выделить.

Затем используйте метод MeasureString объекта Graphics, чтобы получить местоположение искомого текста в ячейке. Поскольку я использую объект 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);

С этого момента он просто использует FillRectangle и DrawString объекта Graphics:

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

и, конечно, не забудьте установить свойство Handled для e в значение true, когда закончите:

e.Handled = true; 

Да, и еще одна вещь: вам нужно будет сделать недействительной всю сетку или, по крайней мере, ячейки, которые были выделены в предыдущем поиске каждый раз, когда вы будете искать новую строку, в противном случае вы получите сетку, заполненную текст, не имеющий отношения к текущей строке поиска.

2 голосов
/ 10 августа 2010

Я не думаю, что есть какой-то встроенный способ сделать это, но я бы предположил, что вы можете обработать CellPainting событие DataGridView, установить e.Handled = true; и затем нарисовать его самостоятельно, как вам нужно .

Возможно, вы сможете использовать PaintBackground, чтобы минимизировать объем работы, которую вы должны выполнять самостоятельно.

...