web-dev-qa-db-ja.com

RichTextBox文字列のさまざまな部分に色を付ける

RichTextBoxに追加する文字列の一部を色付けしようとしています。異なる文字列から構築された文字列があります。

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

これは、メッセージが作成されるとどのように見えるかです。

[9:23 pm]ユーザー:ここに私のメッセージ。

角かっこ[9:23]を含むすべてを1つの色に、「ユーザー」を別の色に、メッセージを別の色にしたいのです。次に、RichTextBoxに文字列を追加したいと思います。

どうすればこれを達成できますか?

102
Fatal510

以下は、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#コーナー の記事を参照してください。

228
Nathan Baulch

フォントをパラメーターとしてメソッドを拡張しました:

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;
}
12
Renan F.

これは、コードに入れた修正バージョンです(.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を挿入しました
  • 追加された中断/再開レイアウト呼び出し
8
tedebus

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

  • 走る

  • Span

  • 大胆な

  • ハイパーリンク

  • イタリック

  • 下線

  • LineBreak

したがって、パーツの色に応じて文字列を分割し、必要な数のRunオブジェクトを作成する必要があると思います。

4
Elo

それは私のために働いています!皆さんのお役に立てばと思います!

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

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
Honza Nav
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
KhaledDev