我想知道我怎么能得到这个词是当前光标是在WPF的RichTextBox。 我知道,RichTextBox中选中属性。 然而,这只是给了我是在RichTextBox中突出显示的文本。 相反,我想知道这个词光标在即使整个单词不突出。
任何提示赞赏。
非常感谢你。
Answer 1:
安装此功能任意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(...)或任何其他适当根据您是否希望保留位数为好。
提示:提取到一个单独的组件中的扩展方法本访问它需要时。
Answer 2:
OK所以为了解决这个我蛮力迫使它。
我用curCaret.GetTextInRun(LogicalDirection.Backward)
和curCaret.GetTextInRun(LogicalDirection.Forward)
随着preCaretString.LastIndexOf(" ")
和postCaretString.IndexOf(" ")
以及用于分隔词,并得到了其他子分隔。
最后,我添加字符串,字符串下半年上半年获得当前光标指示的话。
我打赌有这样的聪明的方式,但至少在这个问题解决了
Answer 3:
你可以通过鼠标的当前位置CaretPosition
。
不幸的是,没有简单的方法来获得字符插入位置的左/右。 我所知道的获得文本了一个RichTextBox的唯一方法是在这个答案 ,这是一个有点令人费解。 但它会完成什么是必要的。
Answer 4:
由于单词之间用空格分开,你可以到空间被发现通过围绕插入符的运行迭代。 该功能甚至应该工作的时候你RichTextBox
甚至包含不同的字体和字体大小。
public string GetWordByCaret(LogicalDirection direction)
{
// Get the CaretPosition
TextPointer position = this.CaretPosition;
TextPointerContext context = position.GetPointerContext(direction);
string text = string.Empty;
// Iterate through the RichTextBox based on the Start, Text and End of nearby inlines
while (context != TextPointerContext.None)
{
// We are only interested in the text here
//, so ignore everything that is not text
if (context == TextPointerContext.Text)
{
string current = position.GetTextInRun(direction);
// The strings appended based on whether they are before the caret or after it...
// And well...I love switches :)
switch (direction)
{
case LogicalDirection.Backward:
{
int spaceIndex = current.LastIndexOf(' ');
// If space is found, we've reached the end
if (spaceIndex >= 0)
{
int length = current.Length - 1;
if (spaceIndex + 1 <= length)
{
text = current.Substring(spaceIndex + 1, length - spaceIndex) + text;
}
return text;
}
else
text = current + text;
}
break;
default:
{
int spaceIndex = current.IndexOf(' ');
// If space is found, we've reached the end
if (spaceIndex >= 0)
{
int length = current.Length;
if (spaceIndex <= length)
{
text += current.Substring(0, spaceIndex);
}
return text;
}
else
text += current;
}
break;
}
}
// Move to the next position
position = position.GetNextContextPosition(direction);
// Get the next context
if (position != null)
context = position.GetPointerContext(direction);
else
context = TextPointerContext.None;
}
return text;
}
现在,你可以让你插入记号是这样的话。
string before = GetWordByCaret(LogicalDirection.Backward);
string after = GetWordByCaret(LogicalDirection.Forward);
string word = before + after; // :)
Answer 5:
这是我使用LINQ和依赖项属性的替代解决方案:
public class SelectionRichTextBox : RichTextBox
{
public SelectionRichTextBox()
{
// Use base class style
SetResourceReference(StyleProperty, typeof(RichTextBox));
}
public static readonly DependencyProperty SelectedWordProperty =
DependencyProperty.Register(
"SelectedWord",
typeof(string),
typeof(SelectionRichTextBox),
new PropertyMetadata("")
);
public string SelectedWord
{
get
{
return (string)GetValue(SelectedWordProperty);
}
set
{
SetValue(SelectedWordProperty, value);
}
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
TextPointer cursorPosition = CaretPosition;
string strBeforeCursor = cursorPosition.GetTextInRun(LogicalDirection.Backward);
string strAfterCursor = cursorPosition.GetTextInRun(LogicalDirection.Forward);
string wordBeforeCursor = strBeforeCursor.Split().Last();
string wordAfterCursor = strAfterCursor.Split().First();
string text = wordBeforeCursor + wordAfterCursor;
SelectedWord = string.Join("", text
.Where(c => char.IsLetter(c))
.ToArray());
base.OnMouseUp(e);
}
}
在这之后,你可以在这样的结合使用:
<custom:SelectionRichTextBox
SelectedWord="{Binding SelectedWord, Mode=OneWayToSource}"/>
文章来源: Way to obtain the word cursor is on, in WPF RichTextBox Control