エディタの行番号には論理行と物理行があります。両者はどう違うのかですが、これによると諸説あるそうです。ただ改行を1行と見なすのが論理行というのが多数派のようです。

前回のプログラム

行番号を表示させる方法 内容が同期されたRichTextBox(その24)

これは表示行を表示するものでした。今回は行数は改行コードで数えます。

ではどうすればいいのでしょうか。行番号を表示するメソッドとして以下のようなものを作りました。

GetFirstCharIndexFromLineの引数は表示行の行番号です。論理行の先頭である必要条件は表示行の先頭であることです。そこで前回同様、表示行の先頭を求めてこれが論理行の先頭であるかどうかを調べます。

論理行の先頭なのかどうかはその前の文字を調べて改行コードであるかどうかで判断することができます。また論理行の先頭であることがわかった場合、それは何行目なのかを知る必要があります。これはそれより前に改行コードが何個あるか数えればわかります。

まずRichTextBoxの内容が変更されたら表示されている文字列を取得しましょう。

スクロールされたとき、編集されたときに以下の処理をおこないます。

あとはスクロールされたときと編集されたときに自作したDrawLineNumber2()メソッドを呼べばいいのかというとそうではありません。

RichTextBox1_VScrollはスクロールされたときに呼び出されるハンドラ、RichTextBox1_TextChangedは文書が変更されたときに呼び出されるのですが、長い文字列が入力されてスクロールがおきるときはRichTextBox1_VScrollが先で、RichTextBox1_TextChangedはそのあとに呼び出されます。そのため以下のコードでは例外が発生する場合があります。

そこでタイマーをつかって少し時間をずらします。

これだと問題はおきません。

以下は上記のクラスを継承したクラスです。カーソルが移動するとカーソル位置がある論理行の行数と行頭からの位置を表示させることができます。