話題(スレッド): カレント行の取得方法を教えてください。

カレント行の取得方法を教えてください。 (2016-11-17 17:27, ganohr, #79043)

はじめまして。面白いコンポーネントの公開ありがとう御座います。

アウトラインエディタを自作してみたいと思い、使用させていただいております。

現在、カレント行の内容を取得しようと試みていますが、
折り返しが有効になった状態で以下のコードを実行するとエラーが起こります。

int lineIndex;
int columnIndex;
azuki.GetLineColumnIndexFromCharIndex(azuki.CaretIndex, out lineIndex, out columnIndex);

int headColumn = azuki.GetCharIndexFromLineColumnIndex(lineIndex, 0);
int lineLength = azuki.GetLineLength(lineIndex);
var line = azuki.GetTextInRange(headColumn, headColumn + lineLength);

Debug.WriteLine(
"Index {0} : ({1}, {2}), head : {3}, depth = {4}, line = {5}"
, azuki.CaretIndex
, lineIndex
, columnIndex
, headColumn
, line
);

エラー詳細:
エラー発生箇所:azuki.GetLineLength(lineIndex)の呼び出し
System.ArgumentOutOfRangeException: Invalid line index was given (lineIndex:1, this.LineCount:1).
パラメーター名:lineIndex



例えば1行目をずっとAキーを押して文字入力していくと、AAAA…と敷き詰められ、任意の位置で折り返され、物理行は1で論理行は2となりますが、GetLineColumnIndexFromCharIndexを用いて得られるlineIndexは物理行で、GetLineLengthは論理行で指定しないといけない? ため、GetLineLengthの指定時にOutOfRangeが発生します。

そもそも

azuki.GetLineColumnIndexFromCharIndexに、azuki.CaretIndexを使ったらいけないような感じを受けるのですが、いまいち分かりませんでした。

お手数をおかけして申し訳ありませんが、解決策をご教授頂ければ幸いです。m(_ _)m

メッセージ #79043 への返信×

ログインしていません。投稿を区別するために投稿者のニックネームをつけてください(ニックネームの一意性は保証されません。全く別の人も同じ名前を利用することが可能ですので本人であることの特定には利用できません。本人であることを保証したい場合にはログインして投稿を行なってください)。 ログインする

Re: カレント行の取得方法を教えてください。 (2016-11-18 22:02, sgry, #79048)

ganohrさん、

山本(sgry)です。はじめまして。

すみません、諸事情あってWindows機が無い状況なので細かい部分で間違っているかもしれませんが、ご容赦ください。。

ご察しの通りAzukiの中にも純粋な論理行(テキストデータとしての行)とスクリーン行(表示上の行)は区別する必要があります。テキストデータはDocumentが、表示に関するデータはViewが管理しています。なので、論理行を扱う場面では常にDocumentのメソッドを、スクリーン行を扱う場面ではViewのメソッドを呼ぶと安全です。

AzukiControlも行を扱うメソッドを持っているのですが、利便性を考えて追加したものです。ただ、現在の実装を確認したところGetLineColumnIndexFromCharIndex()はスクリーン行を、GetLineLength()は論理行を扱うような実装になっていました。。これは仕様不良ですね。。不適切な仕様で申し訳ありません。

取り急ぎ、スクリーン行を扱われるようですのでAzukiControl.ViewにアクセスしてIViewの実装を取り出し、そちらのメソッドを使ってみてください。おそらく問題は解決するはずです。


よろしくお願いします。


[メッセージ #79043 への返信]
> はじめまして。面白いコンポーネントの公開ありがとう御座います。
>
> アウトラインエディタを自作してみたいと思い、使用させていただいております。
>
> 現在、カレント行の内容を取得しようと試みていますが、
> 折り返しが有効になった状態で以下のコードを実行するとエラーが起こります。
>
> int lineIndex;
> int columnIndex;
> azuki.GetLineColumnIndexFromCharIndex(azuki.CaretIndex, out lineIndex, out columnIndex);
>
> int headColumn = azuki.GetCharIndexFromLineColumnIndex(lineIndex, 0);
> int lineLength = azuki.GetLineLength(lineIndex);
> var line = azuki.GetTextInRange(headColumn, headColumn + lineLength);
>
> Debug.WriteLine(
> "Index {0} : ({1}, {2}), head : {3}, depth = {4}, line = {5}"
> , azuki.CaretIndex
> , lineIndex
> , columnIndex
> , headColumn
> , line
> );
>
> エラー詳細:
> エラー発生箇所:azuki.GetLineLength(lineIndex)の呼び出し
> System.ArgumentOutOfRangeException: Invalid line index was given (lineIndex:1, this.LineCount:1).
> パラメーター名:lineIndex
>
>
>
> 例えば1行目をずっとAキーを押して文字入力していくと、AAAA…と敷き詰められ、任意の位置で折り返され、物理行は1で論理行は2となりますが、GetLineColumnIndexFromCharIndexを用いて得られるlineIndexは物理行で、GetLineLengthは論理行で指定しないといけない? ため、GetLineLengthの指定時にOutOfRangeが発生します。
>
> そもそも
>
> azuki.GetLineColumnIndexFromCharIndexに、azuki.CaretIndexを使ったらいけないような感じを受けるのですが、いまいち分かりませんでした。
>
> お手数をおかけして申し訳ありませんが、解決策をご教授頂ければ幸いです。m(_ _)m
#79043 への返信

メッセージ #79048 への返信×

ログインしていません。投稿を区別するために投稿者のニックネームをつけてください(ニックネームの一意性は保証されません。全く別の人も同じ名前を利用することが可能ですので本人であることの特定には利用できません。本人であることを保証したい場合にはログインして投稿を行なってください)。 ログインする