Color of various parts of a RichTextBox string

I am trying to color parts of a string being added to a RichTextBox. I have a string built from different lines.

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

This will look like a message after creating it.

[9:23 pm] User: my message is here.

I want everything inside, including the brackets [9:23], to be in one color, “user” in a different color, and the message in a different color. Then I would like the string to be added to my RichTextBox.

How can i do this?

+95
string c # colors winforms richtextbox
Dec 18 '09 at 4:22
source share
8 answers

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 here is how you 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(); 

Please note that you may notice flickering if you display a lot of messages. See this C # Corner for ideas on how to reduce the flickering of a RichTextBox.

+212
Dec 18 '09 at 7:22
source share

I 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; } 
+11
Sep 29 '15 at 18:49
source share

This is a modified version that I injected into my code (I use .Net 4.5), but I think it should work with 4.0 as well.

 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 the original:

  • the ability to add text to a new line or just add it
  • No need to change the choice, it works the same
  • ScrollToCaret is inserted to force autoscrolling
  • added pause / resume layout invitations
+7
Feb 16 '17 at 12:17
source share

I think changing the "selected text" in a RichTextBox is the wrong way to add colored text. So, here is a way 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 a property of the RichTextBox content. This is a collection of paragraph elements. The content of each paragraph element may contain the following elements:

  • Queue

  • InlineUIContainer

  • Run

  • span

  • Fatty

  • Hyperlink

  • italic

  • underline

  • Line break

Therefore, I think that you need to split your line depending on the color of the part and create as many Run objects as necessary.

+2
Mar 08 '18 at 13:36
source share

It works for me! I hope this will be useful for 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; } 
+1
Dec 09 '18 at 13:34
source share

Selecting a text, as someone said, may appear briefly. There are no other solutions to the problem in Windows Forms applications , but today I found a bad, working and way to solve it: you can put the PictureBox in an overlay on the RichtextBox with a screenshot if during the selection and changing the color or font, creating it after everyone reappears when operation completed.

The code is here ...

 //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(); 

Better use WPF; This solution is not perfect, but it works for Winform.

0
Dec 24 '16 at 9:21
source share
 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; } 
0
Dec 14 '17 at 8:11
source share

Using Selection in WPF, aggregating from several other answers, no other code is needed (except for the Severity enumeration and GetSeverityColor function)

  public void Log(string msg, Severity severity = Severity.Info) { string ts = "[" + DateTime.Now.ToString("HH:mm:ss") + "] "; string msg2 = ts + msg + "\n"; richTextBox.AppendText(msg2); if (severity > Severity.Info) { int nlcount = msg2.ToCharArray().Count(a => a == '\n'); int len = msg2.Length + 3 * (nlcount)+2; //newlines are longer, this formula works fine TextPointer myTextPointer1 = richTextBox.Document.ContentEnd.GetPositionAtOffset(-len); TextPointer myTextPointer2 = richTextBox.Document.ContentEnd.GetPositionAtOffset(-1); richTextBox.Selection.Select(myTextPointer1,myTextPointer2); SolidColorBrush scb = new SolidColorBrush(GetSeverityColor(severity)); richTextBox.Selection.ApplyPropertyValue(TextElement.BackgroundProperty, scb); } richTextBox.ScrollToEnd(); } 
0
Nov 01 '18 at
source share



All Articles