none
C# .NetFrameWork4.0 RichTextBoxにおいての色変更について RRS feed

  • 質問

  • C#でRichTextBoxを使用するプログラムを組んでいます。

    プラグイン等を認識した際に情報を表示するアプリケーション内コンソールのようなものに使うのですが、以下のように組みました。

    ConsoleTextBoxはRichTextBox

    ConsoleMessageというのは、独自定義のクラスで、内部に、

     

    • String Message・・・リッチテキストボックスに表示するメッセージ
    • Color txtColor・・・リッチテキストボックスに表示するメッセージのカラー
    • Color BackColor・・・リッチテキストボックスに表示するメッセージの背景色

     

    を持っていて、ConsoleManager.GetMessages()で今までに出されたメッセージを返すという処理をしています。

    デバッグをしたのですが、イマイチわかりませんでした。なお、foreach内のmsgについては、見たところ特に問題はありませんでした。意図したとおりの変数が来ています。

     

                int start = this.ConsoleTextBox.SelectionStart;//最初に選択されている位置を取得
                int defaultlength = this.ConsoleTextBox.SelectionLength;//最初に選択されている文字数を取得
                List<ConsoleMessage> msgs = ConsoleManager.GetMessages();//メッセージのリストを取得
                foreach (ConsoleMessage msg in msgs)
                {
                    int end = this.ConsoleTextBox.TextLength;//現在のテキストボックスの終点
                    this.ConsoleTextBox.Text += msg.Message;//まずメッセージを追加
                    this.ConsoleTextBox.Select(endmsg.Message.Length + end);//メッセージを追加した分だけ選択する。
                    this.ConsoleTextBox.SelectionColor = msg.txtColor;//テキスト色の設定
                    this.ConsoleTextBox.SelectionBackColor = msg.BackColor;//テキスト背景色の設定
                }
                this.ConsoleTextBox.Select(startdefaultlength);//元のテキスト選択位置に戻す。

     

    例えば、msgsに以下のようなリストを与えたところ、

    (Messages,txtColor,BackColor)

     

    ("テスト1"Color.BlueColor.Red)
    ("テスト2"Color.BlueColor.Blue)
    ("テスト3"Color.RedColor.White)
    ("テスト4"Color.RedColor.Gold)

     

    テスト1テスト2テスト3テスト4

    となってしまいます。

    テスト1テスト2テスト3テスト4

    本来なら、こうなってほしいのですが、どこが間違っているのでしょうか?わかりにくい質問だと思いますが、よろしくお願いします。

    2011年3月14日 1:47

回答

  • それは Text += msg.Message; を実行しているからです。

    Text += msg.Message; は Text = Text + msg.Message; と等価です。
    そして、Text プロパティで得られる文字列は書式情報を含みません。
    「テスト3」までの文字列にせっかく付与した背景色・文字色を失わせて「テスト4」を加えた文字列を設定しているので、最初の文字色・背景色と最後の文字色・背景色が残ります。

    この問題を解消したいのであれば、Text プロパティを使わないことです。
    すでにご自身で返信されているように、SelectedText プロパティで部分的に文字列を書き換えるスタイルもありでしょう。

    元の形に近いコードであれば、Text += の代わりに AppendText メソッドを使ってください。
    ただし、その場合でも、Select メソッドの第 2 引数の意味を調べ直してくださいね。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク Lime_Streem 2011年3月19日 4:37
    2011年3月14日 14:06
    モデレータ

すべての返信

  • foreach (ConsoleMessage msg in msgs)
    {
      this.ConsoleTextBox.SelectionColor = msg.txtColor;//テキスト色の設定
      this.ConsoleTextBox.SelectionBackColor = msg.BackColor;//テキスト背景色の設定
      this.ConsoleTextBox.SelectedText = msg.Message;
    }
    
    順番を変えたらうまくいってるみたいですが、どうしてかはわかりません。
    2011年3月14日 6:43
  • それは Text += msg.Message; を実行しているからです。

    Text += msg.Message; は Text = Text + msg.Message; と等価です。
    そして、Text プロパティで得られる文字列は書式情報を含みません。
    「テスト3」までの文字列にせっかく付与した背景色・文字色を失わせて「テスト4」を加えた文字列を設定しているので、最初の文字色・背景色と最後の文字色・背景色が残ります。

    この問題を解消したいのであれば、Text プロパティを使わないことです。
    すでにご自身で返信されているように、SelectedText プロパティで部分的に文字列を書き換えるスタイルもありでしょう。

    元の形に近いコードであれば、Text += の代わりに AppendText メソッドを使ってください。
    ただし、その場合でも、Select メソッドの第 2 引数の意味を調べ直してくださいね。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク Lime_Streem 2011年3月19日 4:37
    2011年3月14日 14:06
    モデレータ
  • 私は元質問者ではないですが、勉強になりました。ありがとうございました。
    2011年3月16日 0:30
  • 静岡での震度6強の地震に巻き込まれ返信が遅くなってしまいました。すいませんでした。

     

    回答のほう、非常にわかりやすくありがとうございます。

    RichTextBoxクラスのSelectメソッドの第二引数は、選択する文字数でしたか、選択の終点だと思っていました。ご指摘ありがとうございました。

    2011年3月19日 5:04