RichTextBox 문자열의 다른 부분에 색상 지정


109

RichTextBox에 추가 할 문자열의 일부를 색칠하려고합니다. 다른 문자열로 만든 문자열이 있습니다.

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

이것이 생성 된 메시지의 모습입니다.

[9:23 pm] 사용자 : 여기에 내 메시지가 있습니다.

괄호 [9:23]를 포함한 모든 항목은 하나의 색상으로, '사용자'는 다른 색상으로, 메시지는 다른 색상으로 지정합니다. 그런 다음 RichTextBox에 문자열을 추가하고 싶습니다.

어떻게 할 수 있습니까?



5
검색을했는데 유용한 정보가 없습니다.
Fatal510 2009

이 간단한 솔루션에 감사드립니다. 텍스트를 추가 할 때마다 AppendText (...)를 사용하는 것을 잊지 마십시오. '+ ='연산자를 사용하지 마십시오. 그렇지 않으면 적용된 색상이 삭제됩니다.
Xhis 2017-04-04

답변:


238

다음은 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();

많은 메시지를 출력하는 경우 약간의 깜박임이 나타날 수 있습니다. RichTextBox 깜박임을 줄이는 방법에 대한 아이디어는 이 C # Corner 문서를 참조하십시오 .


3
나는 이것에 약간의 문제가 있었다. 다른 곳에서 사용 box.Text += mystring했기 때문에 모든 색상이 사라졌습니다. 이것을로 바꾸었을 때 box.AppendText(mystring), 그것은 매력처럼 작동했습니다.
Natrium 2011

3
다른 색상으로 문자열을 추가 할 때 색상이 사라지는 코드에 문제가 있습니다. 유일한 차이점은 이전에 만든 richtextbox에 var 상자를 할당하는 것입니다 ....
manu_dilip_shah

내가 뭘 잘못하고 있니 ... "SelectionStart"가 RichTextBox의 속성이 아니거나 적어도 액세스 할 수 없습니까? "Selection"을 찾았지만 가져 오기 전용 속성입니다 ...
00jt

2
이것은 특히 WinForms를위한 것입니다. 혹시 WPF를 사용하고 계십니까?
Nathan Baulch 2014 년

나는 과부하 ikee가 없습니다, 오직 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의 콘텐츠 속성입니다. Paragraph 요소의 모음입니다. 각 단락 요소의 내용은 다음 요소를 포함 할 수 있습니다.

  • 인라인

  • InlineUIContainer

  • 운영

  • 스팬

  • 굵게

  • 하이퍼 링크

  • 이탤릭체

  • 밑줄

  • 줄 바꿈

그래서 부품 색상에 따라 끈을 나눠서 Run필요한만큼의 오브젝트를 만들어야한다고 생각 합니다.


나는 이것이 내가 정말로 찾고 있던 대답이기를 바랐지만 WinForms 대답이 아닌 WPF 대답 인 것 같습니다.
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

WPF의 Selection을 사용하여 여러 다른 답변에서 집계하면 다른 코드가 필요하지 않습니다 (Severity 열거 형 및 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.