Измените цвет только части текста внутри ячейки представления сетки данных с помощью c# - PullRequest
0 голосов
/ 04 апреля 2020

Я хочу изменить цвет данного поискового текста в DataGridView, но данные на арабском c. Я пробовал событие CellPainting, чтобы найти границы текста для поиска и нарисовать FillRectangle, но я хочу изменить цвет, не выделяя текст для поиска.

Вот две цифры:

Первая цифра I хочу то же самое: The first figure I want is the same:

Вторая фигура в форме, которую я использовал: The second figure photo of the form he used:

Это код, который я б

if ((e.RowIndex <= -1 ? false : e.ColumnIndex > -1))
        {
            string str = txtSearch.Text.Trim();
            if (!string.IsNullOrWhiteSpace(str))
            {
                string[] strArrays = str.Split(new char[] { ' ' });
                List<Rectangle> rectangles = new List<Rectangle>();
                string[] strArrays1 = strArrays;
                for (int i = 0; i < (int)strArrays1.Length; i++)
                {
                    string str1 = strArrays1[i];
                    string str2 = e.FormattedValue.ToString();
                    int num = str2.ToLower().IndexOf(str1.ToLower());
                    if (num >= 0)
                    {
                        e.Handled = true;
                        e.PaintBackground(e.CellBounds, true);
                        Rectangle y = new Rectangle();
                        Rectangle cellBounds = e.CellBounds;
                        y.Y = cellBounds.Y + 2;
                        cellBounds = e.CellBounds;
                        y.Height = cellBounds.Height - 5;
                        string str3 = str2.Substring(0, num);
                        string str4 = str2.Substring(num, str1.Length);
                        Graphics graphics = e.Graphics;
                        Font font = e.CellStyle.Font;
                        cellBounds = e.CellBounds;
                        Size size = TextRenderer.MeasureText(graphics, str2, font, cellBounds.Size);
                        Graphics graphic = e.Graphics;
                        Font font1 = e.CellStyle.Font;
                        cellBounds = e.CellBounds;
                        Size size1 = TextRenderer.MeasureText(graphic, str3, font1, cellBounds.Size);
                        Graphics graphics1 = e.Graphics;
                        Font font2 = e.CellStyle.Font;
                        cellBounds = e.CellBounds;
                        Size size2 = TextRenderer.MeasureText(graphics1, str4, font2, cellBounds.Size);
                        cellBounds = e.CellBounds;
                        int width = (cellBounds.Width - size.Width) / 2;
                        int x = e.CellBounds.X;
                        cellBounds = e.CellBounds;
                        int width1 = x + cellBounds.Width;
                        y.X = width1 - size1.Width - size2.Width + 5 - width;
                        y.Width = size2.Width;
                        rectangles.Add(y);
                    }
                }
                if (rectangles.Count > 0)
                {
                    SolidBrush solidBrush = new SolidBrush(Color.Yellow);
                    foreach (Rectangle rectangle in rectangles)
                    {
                        e.Graphics.FillRectangle(solidBrush, rectangle);
                    }
                    solidBrush.Dispose();
                    e.PaintContent(e.CellBounds);
                }
            }
        }

1 Ответ

0 голосов
/ 05 апреля 2020

Graphics.FillRectangle не изменит ForeColor. Я изменил тогда событие CellPainting. Я использую Graphics.DrawString для изменения ForeColor.

    if ((e.RowIndex <= -1 ? false : e.ColumnIndex > -1))
        {
            string str = txtSearch.Text.Trim();
            if (!string.IsNullOrWhiteSpace(str))
            {
                string[] strArrays = str.Split(new char[] { ' ' });
                string[] strArrays1 = strArrays;
                for (int i = 0; i < (int)strArrays1.Length; i++)
                {
                    string str1 = strArrays1[i];
                    string str2 = e.FormattedValue.ToString();
                    int num = str2.ToLower().IndexOf(str1.ToLower());
                    if (num >= 0)
                    {
                        e.Handled = true;
                        e.PaintBackground(e.CellBounds, true);
                        Size size = TextRenderer.MeasureText(e.Graphics, str2, e.CellStyle.Font, e.CellBounds.Size);
                        Size searchSize = TextRenderer.MeasureText(e.Graphics, str1, e.CellStyle.Font, e.CellBounds.Size);
                        List<int> indexes = str2.AllIndexesOf(str1).ToList<int>();
                        string leadingPart = string.Empty;
                        string printString = string.Empty;


                        for (int index = 0; index < str2.Length; index++)
                        {
                            if (indexes.Contains(index))//Search string starts here
                            {
                                leadingPart = str2.Substring(0, index);//leading part of the string
                                Size leadingSize = TextRenderer.MeasureText(e.Graphics, leadingPart, e.CellStyle.Font, e.CellBounds.Size);
                                Rectangle rect = new Rectangle(new Point(e.CellBounds.X + leadingSize.Width, e.CellBounds.Y + 4), searchSize);
                                SolidBrush brush = new SolidBrush(Color.Green);
                                e.Graphics.DrawString(str1, e.CellStyle.Font, brush, rect);
                                brush.Dispose();
                                index += str1.Length - 1;
                            }
                            else
                            {
                                int nextIndex = indexes.FirstOrDefault(x => x > index);
                                leadingPart = str2.Substring(0, index);
                                printString = index < nextIndex ? str2.Substring(index, nextIndex - index) : str2.Substring(index);

                                Size leadingSize = TextRenderer.MeasureText(e.Graphics, leadingPart, e.CellStyle.Font, e.CellBounds.Size);
                                Size printSize = TextRenderer.MeasureText(e.Graphics, printString, e.CellStyle.Font, e.CellBounds.Size);
                                Rectangle rect;
                                if (index > 0)
                                    rect = new Rectangle(new Point(e.CellBounds.X + leadingSize.Width, e.CellBounds.Y + 4), printSize);//4 is for adjusting the text top position
                                else
                                    rect = new Rectangle(new Point(e.CellBounds.X, e.CellBounds.Y + 4), printSize);
                                SolidBrush brush = new SolidBrush(Color.Black);
                                e.Graphics.DrawString(printString, e.CellStyle.Font, brush, rect);
                                brush.Dispose();
                                index += printString.Length - 1;
                            }
                        }
                    }
                }
            }
        }

Обратите внимание, что AllIndexesOf является расширением метод для нахождения всех вхождений определенной строки в заданной длинной строке, которую я получил из этого поста .

    public static IEnumerable<int> AllIndexesOf(this string sourceString, string subString)
    {
        return Regex.Matches(sourceString, subString,RegexOptions.IgnoreCase).Cast<Match>().Select(m => m.Index);
    }

Надеюсь, это поможет.

...