読者です 読者をやめる 読者になる 読者になる

RのSkyrim Mod開発日記

SkyrimのMod開発を中心に、備忘録などを載せていきます。

C#でリッチテキストのRtfの追記を行う

やりたいこと

RichTextBoxコントロールで書式変更した後、プログラムから文字列を追加する際に、書式設定を維持する方法について記載します。

結論

次のようなコードで対処が必要です。

RichTextBox rich = new RichTextBox();
rich.Text = addText;
rich.Select(0, rich.TextLength);
rich.SelectionBackColor = Color.Pink;

richTextBox2.SelectionStart = richTextBox2.TextLength;
richTextBox2.SelectedRtf = rich.Rtf;

この例では、追加の文字列をいったん別のRichTextBoxで書式設定などを行い、文字列を追加するRichTextBoxの末尾を選択して、選択範囲にRtf形式で追加するといった方法になります。(※なお、これだと段落が分かれ、追加毎に一つ余分に改行があるひょうじになるかと思いますので、そのような場合、別途対処が必要になるかと思います、。)

背景

ログビューワーの作成(RSkyrimLogViewer)を行っていまして、"error:"という文字列があった場合、該当箇所の背景色を赤くするなど書式変更をする機能を実装しようとしていました。
当初、"error:"が見つかったら、該当のログ範囲をSelectメソッドで選択し、SelectionBackColorメソッドで変更するようにしていましたが、実行したところ、背景色が変わりません。しかし、"error:"だけの項目で絞り込むと表示されます。

あれっと思い次のような簡易コードをステップ実行で確認します。

richTextBox2.Text = "a";
richTextBox2.Update();

richTextBox2.Text += "b";
richTextBox2.Select(1, 1);
richTextBox2.Update();

richTextBox2.SelectionBackColor = Color.Pink;
richTextBox2.Update();

richTextBox2.Text += "c";
richTextBox2.Update();

Color.Pinkを設定した直後は背景色が変わり、"c"を追記したところで背景色が戻ってしまいます。
そこで、やっとRtfで操作しなければいけいないことに気がつきます。

実現に至るまでの流れ

RichTextBoxコントロールでの書式変更は、基本的に次のような方法で行うかと思います。

richTextBox2.Select(1, 10);
richTextBox2.SelectionFont = new Font(richTextBox1.Font, FontStyle.Bold);
rich.SelectionColor = Color.Red;

RichTextBox内のTextプロパティ上での任意の文字範囲について、Selectメソッドや、SelectionStartメソッドで選択し、Selectionの後に続く各メソッド(例:SelectionBackColor)で変更するといった感じです。
そうすると、中ではRich Text Formatに置き換えてくれるといった感じでしょうか。

しかしながら、ログビューワーのように、どんどんと文字列を追記していく場合、そのままTextプロパティに追記すると書式がリセットされてしまうようです。

このため、書式設定した個所を保ちつつ文字列の追記をするには、Rich Text Formatで処理するRtfプロパティでの操作が必要になるかと思われます。
例えば、ファイルを読み込んで、任意のキーワードの文字列を書式変更した後、何らかのタイミングでプログラムから文字列を追加するのに、書式変更したものを維持するには、次のようにするようです。

RichTextBox rich = new RichTextBox();
rich.Text = addText;
rich.Select(0, rich.TextLength);
rich.SelectionBackColor = Color.Pink;

richTextBox2.SelectionStart = richTextBox2.TextLength;
richTextBox2.SelectedRtf = rich.Rtf;

Qiitaで作り直した記事

qiita.com

以上