カーソル位置は何行目か?
カーソル位置の行を処理したいことってありますよね?
自分は、テキストから行単位で音声合成するアプリケーションを作るときに、「カーソル行のテキストを読み上げ」という機能を付けたくてこういう処理を実装したことがあります。
カーソル位置の取得
カーソル位置の取得は
System.Windows.Forms.TextBox.SelectionStart
で得られます(厳密には選択位置の先頭。選択されていないときはカーソル位置になります)
そして、
System.Windows.Forms.TextBox.GetLineFromCharIndex(Int32)
で指定の文字位置の先頭からの行数を得られます。
ところが、このSystem.Windows.Forms.TextBox.GetLineFromCharIndex(Int32)
は論理行ではなく画面上の表示行を返します。これはこれで意味があるのかもしれませんが、論理行を得る関数はありません。
そこで、発想を変えます。
Linqでサクッと解決
C#といえば、Linqですので、Linqでサクッと解決しちゃいましょう。
カーソル位置の行数というのは、カーソル位置までのテキストの中の改行コードの数と同じです。
そこで、こんなコードを書きます。
private int GetLogicalLine(TextBox textBox1)
{
var posStart = textBox1.SelectionStart;
var lineStart = textBox1.Text.Take(posStart).Count(p => p == '\n');
return lineStart;
}
こうすれば論理行を容易に取得することができます。String.Substringとかでとってはいけません。この関数はわざわざStringオブジェクトを生成してしまいます。StringはIEnumerableインターフェースを持っていて、Enumerableとして利用できます。文字の抜き出しはTakeでできますし、その後のカウントも含めてその場でカウントします。