Color different parts of a RichTextBox string
Solution 1
Here is an extension method that overloads the AppendText
method with a color parameter:
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;
}
}
And this is how you would use it:
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();
Note that you may notice some flickering if you're outputting a lot of messages. See this C# Corner article for ideas on how to reduce RichTextBox flicker.
Solution 2
I have expanded the method with font as a parameter:
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;
}
Solution 3
This is the modified version that I put in my code (I'm using .Net 4.5) but I think it should work on 4.0 too.
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();
}
Differences with original one:
- Possibility to add text to a new line or simply append it
- No need to change selection, it works the same
- Inserted
ScrollToCaret
to force autoscroll - Added
SuspendLayout
/ResumeLayout
calls for better performance
Solution 4
EDIT : sorry this is a WPF answer
I think modifying a "selected text" in a RichTextBox isn't the right way to add colored text. So here a method to add a "color block" :
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);
From MSDN :
The Blocks property is the content property of RichTextBox. It is a collection of Paragraph elements. Content in each Paragraph element can contain the following elements:
Inline
InlineUIContainer
Run
Span
Bold
Hyperlink
Italic
Underline
LineBreak
So I think you have to split your string depending on parts color, and create as many Run
objects as needed.
Solution 5
It`s work for me! I hope it will be useful to you!
public static RichTextBox RichTextBoxChangeWordColor(ref RichTextBox rtb, string startWord, string endWord, Color color)
{
rtb.SuspendLayout();
Point scroll = rtb.AutoScrollOffset;
int slct = rtb.SelectionIndent;
int ss = rtb.SelectionStart;
List<Point> ls = GetAllWordsIndecesBetween(rtb.Text, startWord, endWord, true);
foreach (var item in ls)
{
rtb.SelectionStart = item.X;
rtb.SelectionLength = item.Y - item.X;
rtb.SelectionColor = color;
}
rtb.SelectionStart = ss;
rtb.SelectionIndent = slct;
rtb.AutoScrollOffset = scroll;
rtb.ResumeLayout(true);
return rtb;
}
public static List<Point> GetAllWordsIndecesBetween(string intoText, string fromThis, string toThis,bool withSigns = true)
{
List<Point> result = new List<Point>();
Stack<int> stack = new Stack<int>();
bool start = false;
for (int i = 0; i < intoText.Length; i++)
{
string ssubstr = intoText.Substring(i);
if (ssubstr.StartsWith(fromThis) && ((fromThis == toThis && !start) || !ssubstr.StartsWith(toThis)))
{
if (!withSigns) i += fromThis.Length;
start = true;
stack.Push(i);
}
else if (ssubstr.StartsWith(toThis) )
{
if (withSigns) i += toThis.Length;
start = false;
if (stack.Count > 0)
{
int startindex = stack.Pop();
result.Add(new Point(startindex,i));
}
}
}
return result;
}
Comments
-
Essam Ahmed over 2 years
I'm trying to color parts of a string to be appended to a RichTextBox. I have a string built from different strings.
string temp = "[" + DateTime.Now.ToShortTimeString() + "] " + userid + " " + message + Environment.NewLine;
This is what the message would look like once it is constructed.
[9:23pm] User: my message here.
I want everything within and including the brackets [9:23] to be one color, 'user' to be another color and the message to be another color. Then I'd like the string appended to my RichTextBox.
How can I accomplish this?
-
Natrium about 12 yearsI had some trouble with this. I used in another place
box.Text += mystring
and so all the colors disappeared. When I replaced this withbox.AppendText(mystring)
, it worked like a charme. -
manu_dilip_shah about 12 yearsI have some trouble with the code the color dissapears on adding string in some other color.The only difference is i am assigning var box to a previously made richtextbox....
-
00jt over 10 yearsWhat am i doing wrong... "SelectionStart" is not a property of a RichTextBox (or i can't access it at least)? I found "Selection" but it is a get-only property...
-
Nathan Baulch over 10 yearsThis is specifically for WinForms. Are you using WPF by any chance?
-
Jeff almost 6 yearsNote--for this to work you must use the AppendText method. Assigning anything to the text property of the box will break it.
-
Kristen Hammack over 5 yearsI was hoping this was the answer I was really looking for, but it appears to be a WPF answer and not a WinForms answer.
-
vaso123 over 4 yearsI have no overload ikee this, only
AppendText(string text)
with WinForms -
Momoro about 4 years@vaso123 You have to add it yourself. (e.g. Inside of a class file)
-
Josef Bláha almost 4 yearsThis does not solve the given problem, only illustrates how the solution might work.
-
tm1 over 3 yearsNote that colors didn't work for me in the case where the form was not yet shown.