Color output strings in RichTextBox

女生的网名这么多〃 提交于 2019-12-17 17:28:10

问题


I'm working on a program that calls python script and shows the output in richtextbox. I have a problem with coloring specific strings in output. For example: if the string "hey 123" will appear in the output it will colored red. Does someone have an answer? Thanks! snippet of my code:

Process _cmd;
delegate void setTextCallBack(string text);

private void setText (string text)
{
    if (this.richTextBox1.InvokeRequired)
    {
        setTextCallBack d = new setTextCallBack(setText);
        this.Invoke(d, new object[] { text });
    }
    else
    {
        this.richTextBox1.Text += text + Environment.NewLine;
        richTextBox1.SelectionStart = richTextBox1.Text.Length;
        richTextBox1.ScrollToCaret();
    }
}
_cmd = new Process();
_cmd.StartInfo = cmdStartInfo;

if (_cmd.Start())
{
    _cmd.OutputDataReceived += new DataReceivedEventHandler(_cmd_OutputDataReceived);
    _cmd.ErrorDataReceived += new DataReceivedEventHandler(_cmd_ErrorDataReceived);
    _cmd.Exited += new EventHandler(_cmd_Exited);

    _cmd.BeginOutputReadLine();
    _cmd.BeginErrorReadLine();
}
else
{
    _cmd = null;
}
void _cmd_Exited(object sender, EventArgs e)
{
    _cmd.OutputDataReceived -= new DataReceivedEventHandler(_cmd_OutputDataReceived);
    _cmd.Exited -= new EventHandler(_cmd_Exited);
}

void _cmd_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    UpdateConsole(e.Data, Brushes.Red);
}

void _cmd_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    UpdateConsole(e.Data, Brushes.Green);
}

private void UpdateConsole (string text)
{
    UpdateConsole(text, null);
}

private void UpdateConsole(string text, Brush color)
{
    WriteLine(text, color);
}

private void WriteLine(string text, Brush color)
{
    if (text != null)
    {
        setText(text);
    }
}

回答1:


Here is the Golden Rule for RichTextBoxes: Don't touch the Text!

Do not use richTextBox1.Text += "more text" to append Text once you have done any coloring or formatting! This will mess up all formatting you have. There are special functions for everything you need, and you need to use those.

To add use

richTextBox1.AppendText("more text")

Other methods you may need when editing are Copy, Paste & Cut plus of course the select properties and methods, you need for the coloring and formatting as well..

To color a piece of text you need to select it and then apply the Color you want like this:

richTextBox1.SelectionBackColor = Color.MistyRose;  // Backcolor
richTextBox1.SelectionColor = Color.Red;            // TextColor

Other formatting will use SelectionFont, SelectionIndent, SelectionAlignment and then some..

As you see it all works by first selecting and then working on that selection.

In your code you could change the setText method header to:

setText (string text, Color color)

and change its code like this:

else
{
   int start = richTextBox1.Text.Length;  //*
   richTextBox1.AppendText(text + Environment.NewLine);
   richTextBox1.SelectionStart = start;   //*
   richTextBox1.SelectionLength = text.Length;
   richTextBox1.SelectionColor = color;
   richTextBox1.SelectionStart = richTextBox1.Text.Length;
   richTextBox1.SelectionLength = 0;
   richTextBox1.ScrollToCaret();
}

The last three lines are optional; I include them since you seem to want the Caret always at the end..

I would also make it more readable by changing the function's name to something like addText or addColoredText and maybe even make it more flexible by adding a bool parameter to control whether a NewLine should be added or not..

Update:

I notice that you are also calling the UpdateConsole and WriteLine methods with a null for the Brushes. This has two problems:

  • We don't need a Brush but a Color for coloring the RichTextBox.
  • And you can't pass in a null for a Color.

You could workaround by declaring them to be SolidBrushes and the using their brush.Color. But that is just a useless and confusing twist.

Instead pass in the Color you want directly and instead of null pass in Black or the RTF's ForeColor or a default color you define..:

UpdateConsole(text, Color.Black);   

or

UpdateConsole(text, richTextBox1.ForeColor);

etc..

Update 2

Please note the correction (*) in the code; AppendText moves the SelectionStart, so we need to store the start value.

If you have a list of error messages, say

List<string> errors;

You could fill it from a file, maybe like this:

errors = File.ReadAllLines("d:\\errors.txt").ToList();

And then either test for equality:

setText(text,  errors.Contains(text) ? Color.Red : Color.Blue);

Or, if only parts match

setText(text,  isError(text) ? Color.Red : Color.Blue);

using a function like this:

bool isError(string msg)
{ foreach (string err in errors) 
  if (msg.IndexOf(err) >= 0) return true; return false; }


来源:https://stackoverflow.com/questions/25957207/color-output-strings-in-richtextbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!