WPF で、現在のカーソルがオンになっている単語を取得する方法を知りたいRichTextBox
です。RichTextBox
選択プロパティがあることは承知しています。ただし、これは、で強調表示されているテキストのみを提供しますRichTextBox
。代わりに、単語全体が強調表示されていなくても、カーソルが置かれている単語を知りたいです。
どんなヒントでも大歓迎です。
WPF で、現在のカーソルがオンになっている単語を取得する方法を知りたいRichTextBox
です。RichTextBox
選択プロパティがあることは承知しています。ただし、これは、で強調表示されているテキストのみを提供しますRichTextBox
。代わりに、単語全体が強調表示されていなくても、カーソルが置かれている単語を知りたいです。
どんなヒントでも大歓迎です。
この関数を任意の RichTextBox (現在は testRTB と呼ばれる) にアタッチし、結果の [出力] ウィンドウを参照してください。
private void testRTB_MouseUp(object sender, MouseButtonEventArgs e)
{
TextPointer start = testRTB.CaretPosition; // this is the variable we will advance to the left until a non-letter character is found
TextPointer end = testRTB.CaretPosition; // this is the variable we will advance to the right until a non-letter character is found
String stringBeforeCaret = start.GetTextInRun(LogicalDirection.Backward); // extract the text in the current run from the caret to the left
String stringAfterCaret = start.GetTextInRun(LogicalDirection.Forward); // extract the text in the current run from the caret to the left
Int32 countToMoveLeft = 0; // we record how many positions we move to the left until a non-letter character is found
Int32 countToMoveRight = 0; // we record how many positions we move to the right until a non-letter character is found
for (Int32 i = stringBeforeCaret.Length - 1; i >= 0; --i)
{
// if the character at the location CaretPosition-LeftOffset is a letter, we move more to the left
if (Char.IsLetter(stringBeforeCaret[i]))
++countToMoveLeft;
else break; // otherwise we have found the beginning of the word
}
for (Int32 i = 0; i < stringAfterCaret.Length; ++i)
{
// if the character at the location CaretPosition+RightOffset is a letter, we move more to the right
if (Char.IsLetter(stringAfterCaret[i]))
++countToMoveRight;
else break; // otherwise we have found the end of the word
}
start = start.GetPositionAtOffset(-countToMoveLeft); // modify the start pointer by the offset we have calculated
end = end.GetPositionAtOffset(countToMoveRight); // modify the end pointer by the offset we have calculated
// extract the text between those two pointers
TextRange r = new TextRange(start, end);
String text = r.Text;
// check the result
System.Diagnostics.Debug.WriteLine("[" + text + "]");
}
Char.IsLetter(...) を Char.IsLetterOrDigit(...) に変更するか、数字も保持するかどうかに応じて適切に変更します。
ヒント: これを別のアセンブリの拡張メソッドに抽出して、必要なときにいつでもアクセスできるようにします。
OK、これを解決するためにブルートフォース攻撃をしました。
私は
、単語を区切り、部分文字列を取得する他の仕切りcurCaret.GetTextInRun(LogicalDirection.Backward)
と
curCaret.GetTextInRun(LogicalDirection.Forward)
一緒preCaretString.LastIndexOf(" ")
に使用しました。
最終的に、文字列の前半と後半を追加して、現在カーソルのある単語を取得しました。
私はこれを行うための賢い方法があるに違いないが、少なくともこれは問題を解決したpostCaretString.IndexOf(" ")
を介してカーソルの現在位置を取得できますCaretPosition
。
残念ながら、文字をキャレット位置の左右に移動する簡単な方法はありません。RichTextBox からテキストを取得するために私が知っている唯一の方法は、この回答にありますが、これは少し複雑です。しかし、それは必要なことを達成します。