背景
Winform打印后台線程運行時消息,習慣用ListBox,有時候某行消息過長,設置個Tooltip控件提示全部信息。后來無意中看到同事使用RichTextBox打印消息,然后在不同的消息類別上加以不同的顏色做區分,倒也不失為一種辦法,自己覺得這樣還不錯,於是找了資料,然后做成例子,特意分享一下。
常用的消息類別:正常信息、警告信息、錯誤信息。具體效果見下文。
資源下載
實現
主要打印有顏色消息的方法如下:
public static void AppendMsg(this RichTextBox richTextBox1, Color color, string text) { richTextBox1.BeginInvoke(new ThreadStart(() => { lock (richTextBox1) { //為控件輸入焦點 richTextBox1.Focus(); //檢查文本框過長 if (richTextBox1.TextLength > 10000) { richTextBox1.Clear(); } //得到有格式的文本 using (var temp = new RichTextBox()) { temp.SelectionColor = color; if (AutoTime) temp.AppendText(DateTime.Now.ToString("HH:mm:ss ")); temp.AppendText(text); //追加文本 richTextBox1.Select(richTextBox1.Rtf.Length, 0); richTextBox1.SelectedRtf = temp.Rtf; } //設定光標所在位置 //richTextBox1.SelectionStart = richTextBox1.TextLength; //滾動到當前光標處 //richTextBox1.ScrollToCaret(); } })); }
封裝了Info,Warn,Error等方法。

public static partial class ExtendMethod { //控制是否在打印消息時自動添加時間 public static bool AutoTime = true; public static void AppendMsg(this RichTextBox richTextBox1, Color color, string text) { richTextBox1.BeginInvoke(new ThreadStart(() => { lock (richTextBox1) { //為控件輸入焦點 richTextBox1.Focus(); //檢查文本框過長 if (richTextBox1.TextLength > 10000) { richTextBox1.Clear(); } //得到有格式的文本 using (var temp = new RichTextBox()) { temp.SelectionColor = color; if (AutoTime) temp.AppendText(DateTime.Now.ToString("HH:mm:ss ")); temp.AppendText(text); //追加文本 richTextBox1.Select(richTextBox1.Rtf.Length, 0); richTextBox1.SelectedRtf = temp.Rtf; } //設定光標所在位置 //richTextBox1.SelectionStart = richTextBox1.TextLength; //滾動到當前光標處 //richTextBox1.ScrollToCaret(); } })); } public static void Error(this RichTextBox richTextBox1, string text) { richTextBox1.AppendMsg(Color.Red, text); } public static void Warn(this RichTextBox richTextBox1, string text) { richTextBox1.AppendMsg(Color.Violet, text); } public static void Info(this RichTextBox richTextBox1, string text) { richTextBox1.AppendMsg(Color.Green, text); } }
問題
在以上代碼中,其實是構造了局部的RichTextBox,將要顯示的效果先設置在該臨時控件上,然后直接把帶格式的字體設置到原來的控件中。之所這樣繞了一圈,是因為如果直接在原來的控件上(richTextBox1)上操作,會帶來問題,這個問題則是后台線程在打印消息時,點擊richTextBox1輸入框,會將文字格式變成原有的黑色。
下面列舉其他的2種實現方法:

public void AppendMsg(Color color, string text) { lock (richTextBox1) { richTextBox1.AppendText(string.Empty); richTextBox1.SelectionColor = color; richTextBox1.AppendText(DateTime.Now.ToString("HH:mm:ss ")); richTextBox1.AppendText(text); richTextBox1.AppendText("\n"); //設定光標所在位置 richTextBox1.SelectionStart = richTextBox1.TextLength; //滾動到當前光標處 richTextBox1.ScrollToCaret(); } }

public void AppendMsg2(Color color, string text) { lock (richTextBox1) { int p1 = richTextBox1.TextLength; //取出未添加時的字符串長度。 richTextBox1.AppendText(text + "/n"); //保留每行的所有顏色。 // rtb.Text += strInput + "/n"; //添加時,僅當前行有顏色。 int p2 = text.Length; //取出要添加的文本的長度 richTextBox1.Select(p1, p2); //選中要添加的文本 richTextBox1.SelectionColor = color; //設置要添加的文本的字體色 } }
方法一是追加空字符串,然后設置格式,接着追加需要顯示的文字,和操作Word一樣,格式自動與前面保持一致、
方法二則是記錄新加的文本的位置,然后將其選中,接着設置選中文本的顏色。
這2種方法,在點擊控件的時候,均會帶來之前提到的問題,文字變成黑色。當然,如果控件的Enable屬性為false時,自然是可以避免的。所以折衷下來,使用了上述方案。
我做Winform,純屬興趣愛好,言辭不當望海涵。不知道大家有沒有更好的實現方案,歡迎賜教。謝謝。