ระบายสีส่วนต่างๆของสตริง RichTextBox


109

ฉันกำลังพยายามระบายสีส่วนของสตริงเพื่อต่อท้าย RichTextBox ฉันมีสตริงที่สร้างจากสตริงที่แตกต่างกัน

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

นี่คือลักษณะของข้อความเมื่อถูกสร้างขึ้น

[21:23 น.] User: my message here.

ฉันต้องการให้ทุกอย่างภายในและรวมทั้งวงเล็บ [9:23] เป็นสีเดียว 'ผู้ใช้' เป็นสีอื่นและข้อความเป็นสีอื่น จากนั้นฉันต้องการให้สตริงต่อท้าย RichTextBox ของฉัน

ฉันจะทำสิ่งนี้ให้สำเร็จได้อย่างไร?



5
ฉันค้นหาและไม่พบว่ามันมีประโยชน์
Fatal510

ขอบคุณสำหรับวิธีง่ายๆนี้ใช้ได้ดีสำหรับฉัน อย่าลืมใช้ AppendText (... ) ทุกครั้งที่คุณต้องการต่อท้ายข้อความและอย่าใช้ตัวดำเนินการ "+ =" หรือสีที่ใช้จะถูกละทิ้ง
Xhis

คำตอบ:


240

นี่คือวิธีการขยายที่โอเวอร์โหลด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 # Cornerสำหรับแนวคิดเกี่ยวกับวิธีลดการกะพริบของ RichTextBox


3
ฉันมีปัญหากับเรื่องนี้ ฉันใช้ในสถานที่อื่นbox.Text += mystringและสีทั้งหมดจึงหายไป เมื่อฉันแทนที่สิ่งนี้box.AppendText(mystring)มันจะทำงานเหมือนมีเสน่ห์
Natrium

3
ฉันมีปัญหากับรหัสสีจะหายไปในการเพิ่มสตริงในสีอื่นความแตกต่างเพียงอย่างเดียวคือฉันกำหนดกล่อง var ให้กับ richtextbox ที่ทำไว้ก่อนหน้านี้ ....
manu_dilip_shah

ฉันทำอะไรผิด ... "SelectionStart" ไม่ใช่คุณสมบัติของ RichTextBox (หรือฉันไม่สามารถเข้าถึงได้อย่างน้อย)? ฉันพบ "การเลือก" แต่เป็นคุณสมบัติที่ได้รับเท่านั้น ...
00jt

2
โดยเฉพาะสำหรับ WinForms คุณใช้ WPF โดยบังเอิญหรือไม่?
Nathan Baulch

ฉันไม่มีโอเวอร์โหลดสิ่งนี้เฉพาะAppendText(string text)กับ WinForms
vaso123

12

ฉันได้ขยายวิธีการโดยใช้ฟอนต์เป็นพารามิเตอร์:

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;
}

หมายเหตุ - เพื่อให้ได้ผลคุณต้องใช้เมธอด AppendText การกำหนดสิ่งใด ๆ ให้กับคุณสมบัติข้อความของกล่องจะทำให้กล่องเสียหาย
Jeff

9

นี่เป็นเวอร์ชันแก้ไขที่ฉันใส่ในโค้ดของฉัน (ฉันใช้. 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 เพื่อบังคับให้เลื่อนอัตโนมัติ
  • เพิ่มการเรียกใช้โครงร่างระงับ / ดำเนินการต่อ

6

ฉันคิดว่าการแก้ไข "ข้อความที่เลือก" ใน 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 มันเป็นชุดขององค์ประกอบย่อหน้า เนื้อหาในแต่ละองค์ประกอบย่อหน้าสามารถมีองค์ประกอบต่อไปนี้:

  • อินไลน์

  • InlineUIContainer

  • วิ่ง

  • ช่วง

  • ตัวหนา

  • ไฮเปอร์ลิงก์

  • ตัวเอียง

  • ขีดเส้นใต้

  • LineBreak

ดังนั้นฉันคิดว่าคุณต้องแยกสตริงของคุณโดยขึ้นอยู่กับสีของชิ้นส่วนและสร้างRunวัตถุได้มากเท่าที่ต้องการ


ฉันหวังว่านี่จะเป็นคำตอบที่ฉันต้องการจริงๆ แต่ดูเหมือนว่าจะเป็นคำตอบ WPF ไม่ใช่คำตอบของ WinForms
Kristen Hammack

3

มันได้ผลสำหรับฉัน! ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ!

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;
}

0

การเลือกข้อความตามที่ใครบางคนกล่าวไว้การเลือกอาจปรากฏขึ้นในไม่ช้า ในWindows Forms applicationsไม่มีการแก้ปัญหาอื่น ๆ สำหรับปัญหา แต่วันนี้ผมพบว่าไม่ดีทำงานวิธีที่จะแก้: คุณสามารถใส่PictureBoxทับไปRichtextBoxกับหน้าจอของถ้าในระหว่างการเลือกและเปลี่ยนสีหรือตัวอักษรที่ทำให้มันหลังจาก ปรากฏขึ้นอีกครั้งเมื่อการดำเนินการเสร็จสมบูรณ์

รหัสอยู่ที่นี่ ...

//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 มันใช้งานได้


0
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

การใช้ Selection ใน WPF โดยรวบรวมจากคำตอบอื่น ๆ ไม่จำเป็นต้องใช้รหัสอื่น ๆ (ยกเว้นฟังก์ชัน Severity enum และ GetSeverityColor)

 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

ฉันสร้างฟังก์ชันนี้หลังจากค้นคว้าข้อมูลทางอินเทอร์เน็ตเนื่องจากฉันต้องการพิมพ์สตริง XML เมื่อคุณเลือกแถวจากมุมมองตารางข้อมูล

static void HighlightPhrase(RichTextBox box, string StartTag, string EndTag, string ControlTag, Color color1, Color color2)
{
    int pos = box.SelectionStart;
    string s = box.Text;
    for (int ix = 0; ; )
    {
        int jx = s.IndexOf(StartTag, ix, StringComparison.CurrentCultureIgnoreCase);
        if (jx < 0) break;
        int ex = s.IndexOf(EndTag, ix, StringComparison.CurrentCultureIgnoreCase);
        box.SelectionStart = jx;
        box.SelectionLength = ex - jx + 1;
        box.SelectionColor = color1;
        
        int bx = s.IndexOf(ControlTag, ix, StringComparison.CurrentCultureIgnoreCase);
        int bxtest = s.IndexOf(StartTag, (ex + 1), StringComparison.CurrentCultureIgnoreCase);
        if (bx == bxtest)
        {
            box.SelectionStart = ex + 1;
            box.SelectionLength = bx - ex + 1;
            box.SelectionColor = color2;
        }
        
        ix = ex + 1;
    }
    box.SelectionStart = pos;
    box.SelectionLength = 0;
}

และนี่คือวิธีที่คุณเรียกมัน

   HighlightPhrase(richTextBox1, "<", ">","</", Color.Red, Color.Black);

สิ่งนี้ไม่ได้ช่วยแก้ปัญหาที่กำหนดเพียง แต่แสดงให้เห็นว่าวิธีแก้ปัญหานั้นทำงานอย่างไร
Josef Bláha
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.