ネタもと:Insider.NET 会議室【C# RichTextBoxのRTFプロパティを固定するには】
この中で、rich_box.Text = rich_box.Text.Insert(4, "hoge");
ということをしているのですが、さて、ここで期待している動作と、実際におこっている動作は一致しているのでしょうか。
質問の内容から、どの様に考えてコード化したのか、考えます。
この質問の中でやりたいことは、
int ;
とあるものを、
int hoge;
としたいわけですね。で、単純に目で見えることから考えると、「"int ;" という文字列があるので、これの4文字目に "hoge" という文字列を挿入すればよい」となります。そこで RichTextBox のメンバを眺めると、Text プロパティと Rtf プロパティがありました。この2つには、現在表示されている情報がすべて入っています。このことから、これらのプロパティを操作すれば、表示されている内容を操作できるだろうという考えが浮かびます。
そこで、Text プロパティを調べると、string クラスであることがわかります。string クラスを調べると、Insert メソッドを持っており、このメソッドで、文字列の任意の位置に任意の文字列を挿入できることがわかります。うれしいことにバイト数ではなく、文字数でカウントできますから、文字のバイト数から挿入ポイントを探す手間が省けます。ここから、rich_box.Text.Insert(4, "hoge");
というコードが出てきたわけですね。
ところが、Insert メソッドは戻り値を持っています。つまり、操作結果が返ってくるわけです。もっとも、結果を無視してもいいことがあります。"int ;" という文字列が "int hoge;" になれば、戻ってくる "int hoge;" は別に必要ではありません。しかし、実際に rich_box.Text.Insert(4, "hoge");
を実行しても、表示されている文字列は変わりません。そこでもう一度 Text プロパティに戻してやることにしました。すると、"int hoge;" と、全体の色が変わってしまいました。
といったところではないでしょうか。はたして、いったい何を間違ったのでしょう?
まず、設計の面から見ます。設計では、「やりたいことを実行するコード」を考えてはいけません。「やりたいことを実行するために、何が必要か」を考えます。必要なものを揃えようとすると、「コードの断片」つまりクラスやメソッドですね、これらが「何をするものか」ということを、正確に知っておく必要があります。このことは、後のデバッグでも必要です。行わせたいことと、実際に行われていることの差を知らなければ、何が間違っているのかわからないからです。
では、実際に間違っている点はなんでしょう?
まずは、「.NET Framework では、文字列は不変である」ということです。Insert メソッドによって文字列が挿入されたのは、結果として作られた新しい文字列であって、コントロール上に表示されている文字列ではありません。rich_box.Text.Insert(4, "hoge");
ではリッチテキストボックスの文字列は操作されず、新しい文字列が作られます。
しかし、新しい文字列であったとしても、"int hoge;" という文字列ができていれば、問題はないはずです。はい、注目。カラー環境でない方、ごめんなさい。Text プロパティが表現するのは、"int hoge;" という文字列ではなく、"int hoge;" という文字列です。この2つを比べれば、間違っている点は明白ですね。Text プロパティは「書式なし文字列」なのです。
ここでやらなければならないのは、"int ;" を "int hoge;" にすることではありません。RTF はややこしいので HTML で考えますが、
<span style="color:blue;">int</span> ;
という文字列を、
<span style="color:blue;">int</span> hoge;
に変更することです。表示上のカレット位置と、RTF でのカレット位置の同期をとるのが云々というところから、気が付かれているようなのですが。。。
次に、デバッグの面から見ます。デバッグでまずしなければならないのは、「設計意図」と「実装」の差異を見つけることです。掲示板での質問では、「エラーになります」、「出来ません」、「なりませんでした」という言葉が頻繁に出てきますが、どういう意図を持って設計したのかが書いてあることは、ほとんどありません。ただし、「希望する実装」または「現在の実装」は、たいてい書いてあります。間違ってます。エラーになるからバグがあるのではありません。意図と実装にズレがあるから、このズレがバグなんです。意図と実装の2つを比較しなければ、バグは見つかりません。 ただし、タイプミスなど、一部のヒューマンエラーはのぞきます。
しかし、意図と実装のズレを見つけることは、簡単ではありません。なぜなら、「こうしたい」という希望を持って実装しているので、「こう動くはずだ」と思っているからです。この思いが、実装を解析することをジャマします。
このケースでは、Text プロパティが「書式なし文字列」であり、「文字列すべてを表している」ことを失念していることが、掲示板で質問するに至った原因でしょうか。また、設計がきちんと出来ていないことも原因でしょう。RichTextBox のそれぞれのプロパティ、メソッドが「何をするものか」を正しく理解していれば、いつまでも Text プロパティにこだわらず、次にすすめたのではないでしょうか。
SelectedText プロパティ?あ………画像を挿入することで頭がいっぱいで、無視していた...
投稿日時 : 2006年2月17日 22:19