Цвет различных частей строки RichTextBox



Я пытаюсь раскрасить части строки, которые будут добавлены в RichTextBox. У меня есть строка, построенная из разных строк.



string temp = "[" + DateTime.Now.ToShortTimeString() + "] " +
userid + " " + message + Environment.NewLine;


это то, что сообщение будет выглядеть, как только он построен.




[9:23pm] пользователь: мое сообщение здесь.




Я хочу, чтобы все внутри и включая скобки [9:23] было одного цвета, "пользователь" - другого цвета, а сообщение-другого цвета. Тогда я хотел бы, чтобы строка была добавлена к моей RichTextBox.



Как я могу это сделать?

870   6  

6 ответов:

вот метод расширения, который перегружает AppendText метод с параметром цвет:

public static class RichTextBoxExtensions
{
    public static void AppendText(this RichTextBox box, string text, Color color)
    {
        box.SelectionStart = box.TextLength;
        box.SelectionLength = 0;

        box.SelectionColor = color;
        box.AppendText(text);
        box.SelectionColor = box.ForeColor;
    }
}

и вот как бы вы его использовали:

var userid = "USER0001";
var message = "Access denied";
var box = new RichTextBox
              {
                  Dock = DockStyle.Fill,
                  Font = new Font("Courier New", 10)
              };

box.AppendText("[" + DateTime.Now.ToShortTimeString() + "]", Color.Red);
box.AppendText(" ");
box.AppendText(userid, Color.Green);
box.AppendText(": ");
box.AppendText(message, Color.Blue);
box.AppendText(Environment.NewLine);

new Form {Controls = {box}}.ShowDialog();

обратите внимание, что вы можете заметить некоторое мерцание, если вы выводите много сообщений. Смотрите этот угол C# статья для идей о том, как уменьшить мерцание RichTextBox.

я расширил метод с помощью шрифта в качестве параметра:

public static void AppendText(this RichTextBox box, string text, Color color, Font font)
{
    box.SelectionStart = box.TextLength;
    box.SelectionLength = 0;

    box.SelectionColor = color;
    box.SelectionFont = font;
    box.AppendText(text);
    box.SelectionColor = box.ForeColor;
}

Это модифицированная версия, которую я вставил в свой код (я использую .Net 4.5), но я думаю, что он должен работать и на 4.0.

public void AppendText(string text, Color color, bool addNewLine = false)
{
        box.SuspendLayout();
        box.SelectionColor = color;
        box.AppendText(addNewLine
            ? $"{text}{Environment.NewLine}"
            : text);
        box.ScrollToCaret();
        box.ResumeLayout();
}

отличия от оригинала:

  • возможность добавить текст в новую строку или просто добавить его
  • нет необходимости менять выбор, он работает так же
  • вставлен ScrollToCaret для принудительной автопрокрутки
  • добавлена приостановка / возобновление вызовов макета

выбор текста как сказано от кого-то, может выбор появиться на мгновение. В Windows Forms applications других решений проблемы нет, но сегодня я нашел плохой, рабочий, способ решения: вы можете поставить PictureBox в перекрытии в RichtextBox С скриншотом if, во время выбора и изменения цвета или шрифта, что делает его после повторного появления всех, когда операция завершена.

код здесь...

//The PictureBox has to be invisible before this, at creation
//tb variable is your RichTextBox
//inputPreview variable is your PictureBox
using (Graphics g = inputPreview.CreateGraphics())
{
    Point loc = tb.PointToScreen(new Point(0, 0));
    g.CopyFromScreen(loc, loc, tb.Size);
    Point pt = tb.GetPositionFromCharIndex(tb.TextLength);
    g.FillRectangle(new SolidBrush(Color.Red), new Rectangle(pt.X, 0, 100, tb.Height));
}
inputPreview.Invalidate();
inputPreview.Show();
//Your code here (example: tb.Select(...); tb.SelectionColor = ...;)
inputPreview.Hide();

лучше использовать WPF; это решение не идеально, но для Winform это работает.

private void Log(string s , Color? c = null)
        {
            richTextBox.SelectionStart = richTextBox.TextLength;
            richTextBox.SelectionLength = 0;
            richTextBox.SelectionColor = c ?? Color.Black;
            richTextBox.AppendText((richTextBox.Lines.Count() == 0 ? "" : Environment.NewLine) + DateTime.Now + "\t" + s);
            richTextBox.SelectionColor = Color.Black;

        }

Я думаю, что изменение "выделенного текста" в RichTextBox не является правильным способом добавления цветного текста. Так вот способ добавить "цветной блок":

        Run run = new Run("This is my text");
        run.Foreground = new SolidColorBrush(Colors.Red); // My Color
        Paragraph paragraph = new Paragraph(run);
        MyRichTextBlock.Document.Blocks.Add(paragraph);

С MSDN:

свойство Blocks является свойством содержимого RichTextBox. Это коллекция элементов абзаца. Содержание в каждом элементе абзаца может содержать следующие элементы:

  • Inline

  • InlineUIContainer

  • Run

  • Span

  • полужирный

  • гиперссылка

  • Курсив

  • подчеркнуть

  • разрыв строки

поэтому я думаю, что вы должны разделить строку в зависимости от цвета деталей, и создать как можно больше Run объекты необходимый.

Comments

    Ничего не найдено.