Foros: 公開討議 (Thread #38208)

カレント行の取得方法を教えてください。 (2016-11-17 17:27 by 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

Responder al #79043×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar

Re: カレント行の取得方法を教えてください。 (2016-11-18 22:02 by 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
Responder al #79043

Responder al #79048×

You can not use Wiki syntax
You are not logged in. To discriminate your posts from the rest, you need to pick a nickname. (The uniqueness of nickname is not reserved. It is possible that someone else could use the exactly same nickname. If you want assurance of your identity, you are recommended to login before posting.) Entrar