Задать вопрос
@Gepard_vvk

Как можно ускорить кастомную отрисовку в WinForms?

Работаю на WinForms приложением, в котором нужно реализовать проверку правописания.

Для перерисовки формы использую перехват Windows message.
/// <summary>
        /// Processes Windows messages.
        /// </summary>
        /// <param name="msg">
        /// A Windows Message object.
        /// </param>
        protected override void WndProc(ref Message msg)
        {
            switch (msg.Msg)
            {
                case WM_PAINT:
                    Invalidate();
                    base.WndProc(ref msg);

                    if (IsSpellingAutoEnabled)
                    {
                        CustomPaint();
                    }

                    break;

            ...

                default:
                    base.WndProc(ref msg);
                    break;
            }
        }


Метод CustomPaint() выглядит так:
private void CustomPaint()
        {
            Bitmap tempBitmap;
            Graphics bufferGraphics;

            tempBitmap = new Bitmap(Width, Height);
            bufferGraphics = Graphics.FromImage(tempBitmap);
            bufferGraphics.Clip = new Region(ClientRectangle);

            _textBoxGraphics = CreateGraphics();
            bufferGraphics.Clear(Color.Transparent);

            foreach (var wordStartIndex in UnderlinedSections.Keys)
            {
                UnderlineWords(wordStartIndex, bufferGraphics);
            }

            _textBoxGraphics.DrawImageUnscaled(tempBitmap, 0, 0);
        }


В UnderlineWords в буфер добавляются линии, которые нужно нарисовать с пом. такого метода:
private void DrawWave(Graphics bufferGraphics, Point startOfLine, Point endOfLine)
        {
            startOfLine.Y--;
            endOfLine.Y--;

            // kvv: Определяем цвет линий подчеркивания.
            var pen = Pens.Red;

            if ((endOfLine.X - startOfLine.X) >= 4)
            {
                var points = new ArrayList();
                for (int i = startOfLine.X; i <= (endOfLine.X - 2); i += 4)
                {
                    points.Add(new Point(i, startOfLine.Y));
                    points.Add(new Point(i + 2, startOfLine.Y + 2));
                }

                var p = (Point[])points.ToArray(typeof(Point));
                bufferGraphics.DrawLines(pen, p);
            }
        }


При работе этого кода на тексте размером больше 500 символов начинаются сильные тормоза и подвисания приложения. Как можно от этого избавиться? В какую сторону копать?
  • Вопрос задан
  • 3143 просмотра
Подписаться 2 Оценить 2 комментария
Пригласить эксперта
Ответы на вопрос 1
aush
@aush
Не надо так делать. У вас куча логики на отрисовку, конечно, это будет дико медленно работать.

Возьмите стандартный RichTextBox и сделайте как-то так:
richTextBox1.Text = "blah blah meeh";
richTextBox1.SelectionStart = 5;
richTextBox1.SelectionLength = 4;
richTextBox1.SelectionFont = new Font(richTextBox1.SelectionFont, FontStyle.Underline);
// еще варианты:
//richTextBox1.SelectionColor = Color.Red;
//richTextBox1.SelectionBackColor = Color.Yellow;
//повторить для все слов с ошибками


Если критично, чтобы отображение было стандартным (красная волновая линия под черным текстом), то расширьте RichTextBox: geekswithblogs.net/pvidler/archive/2003/10/15/188.aspx
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы