RichTextBox用鼠标点击后得到完整的单词
RichTextBox get full word after clicking on it with the mouse
如何在点击时获得整个单词?
我知道类似的问题已经出现并且我看过了,但出于某种原因,40 行代码有奇怪且非常古老的解决方案。也许有更现代的东西?
使用事件PreviewMouseDown
来select整个词。当然,根据你想要的功能,可以使用类似的事件
private void richTextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
TextSelection ts = richTextBox.Selection;
string text = ts.Text;
if (!string.IsNullOrEmpty(text))
MessageBox.Show(text);
}
下面的代码演示了如何获取 RichTextBox
控件中当前插入符位置的单词。
XAML:
<Window ... >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<RichTextBox Grid.Row="0" x:Name="rtb" AllowDrop="True" VerticalScrollBarVisibility="Auto" Padding="2"
PreviewMouseUp="rtb_PreviewMouseUp" >
<FlowDocument>
<Paragraph FontSize="18" TextAlignment="Left" >
<!-- The RichTextBox control content should defined be here
or use the PASTE command to add some content... -->
</Paragraph>
</FlowDocument>
</RichTextBox>
<Button Grid.Row="2" Click="Button_Click">Mark Current Word</Button>
</Grid>
</Window>
下面的函数获取一个指针,指向从指定方向解析文本的位置,以检测单词边界。 pattern
变量定义了一组可能的单词分隔符。
public static class TextPointerExt
{
public static TextPointer GetEdgeTextPointer(this TextPointer position, LogicalDirection direction)
{
string pattern = @" ,;.!""?"; // Delimiters
int step = direction == LogicalDirection.Forward ? 1 : -1;
for (; position != null;)
{
var text = position.GetTextInRun(direction);
int offset = 0;
int i = direction == LogicalDirection.Forward ? 0 : text.Length - 1;
for (; i >= 0 && i < text.Length; offset++, i += step)
{
if (pattern.Contains(text[i]))
{
return position.GetPositionAtOffset(offset * step, LogicalDirection.Forward);
}
}
position = position.GetPositionAtOffset(offset * step, LogicalDirection.Forward);
for (TextPointer latest = position; ;)
{
if ((position = position.GetNextContextPosition(direction)) == null)
return latest;
var context = position.GetPointerContext(direction);
var adjacent = position.GetAdjacentElement(direction);
if (context == TextPointerContext.Text)
{
if (position.GetTextInRun(direction).Length > 0)
break;
}
else if (context == TextPointerContext.ElementStart && adjacent is Paragraph)
{
return latest;
}
}
}
return position;
}
}
使用GetEdgeTextPointer()
方法判断当前指向的词的例子:
public void GetCurrentWord()
{
TextPointer current = rtb.CaretPosition;
var start = current.GetEdgeTextPointer(LogicalDirection.Backward); // Word position before caret
var end = current.GetEdgeTextPointer(LogicalDirection.Forward); // Word position after caret
if (start is TextPointer && end is TextPointer && start.CompareTo(end) != 0)
{
TextRange textrange = new TextRange(start, end);
// Print the found word to the debug window.
System.Diagnostics.Debug.WriteLine(textrange.Text);
// Select the found word
rtb.Selection.Select(start, end);
}
rtb.Focus();
}
private void rtb_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
GetCurrentWord();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
GetCurrentWord();
}
如何在点击时获得整个单词? 我知道类似的问题已经出现并且我看过了,但出于某种原因,40 行代码有奇怪且非常古老的解决方案。也许有更现代的东西?
使用事件PreviewMouseDown
来select整个词。当然,根据你想要的功能,可以使用类似的事件
private void richTextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
TextSelection ts = richTextBox.Selection;
string text = ts.Text;
if (!string.IsNullOrEmpty(text))
MessageBox.Show(text);
}
下面的代码演示了如何获取 RichTextBox
控件中当前插入符位置的单词。
XAML:
<Window ... >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<RichTextBox Grid.Row="0" x:Name="rtb" AllowDrop="True" VerticalScrollBarVisibility="Auto" Padding="2"
PreviewMouseUp="rtb_PreviewMouseUp" >
<FlowDocument>
<Paragraph FontSize="18" TextAlignment="Left" >
<!-- The RichTextBox control content should defined be here
or use the PASTE command to add some content... -->
</Paragraph>
</FlowDocument>
</RichTextBox>
<Button Grid.Row="2" Click="Button_Click">Mark Current Word</Button>
</Grid>
</Window>
下面的函数获取一个指针,指向从指定方向解析文本的位置,以检测单词边界。 pattern
变量定义了一组可能的单词分隔符。
public static class TextPointerExt
{
public static TextPointer GetEdgeTextPointer(this TextPointer position, LogicalDirection direction)
{
string pattern = @" ,;.!""?"; // Delimiters
int step = direction == LogicalDirection.Forward ? 1 : -1;
for (; position != null;)
{
var text = position.GetTextInRun(direction);
int offset = 0;
int i = direction == LogicalDirection.Forward ? 0 : text.Length - 1;
for (; i >= 0 && i < text.Length; offset++, i += step)
{
if (pattern.Contains(text[i]))
{
return position.GetPositionAtOffset(offset * step, LogicalDirection.Forward);
}
}
position = position.GetPositionAtOffset(offset * step, LogicalDirection.Forward);
for (TextPointer latest = position; ;)
{
if ((position = position.GetNextContextPosition(direction)) == null)
return latest;
var context = position.GetPointerContext(direction);
var adjacent = position.GetAdjacentElement(direction);
if (context == TextPointerContext.Text)
{
if (position.GetTextInRun(direction).Length > 0)
break;
}
else if (context == TextPointerContext.ElementStart && adjacent is Paragraph)
{
return latest;
}
}
}
return position;
}
}
使用GetEdgeTextPointer()
方法判断当前指向的词的例子:
public void GetCurrentWord()
{
TextPointer current = rtb.CaretPosition;
var start = current.GetEdgeTextPointer(LogicalDirection.Backward); // Word position before caret
var end = current.GetEdgeTextPointer(LogicalDirection.Forward); // Word position after caret
if (start is TextPointer && end is TextPointer && start.CompareTo(end) != 0)
{
TextRange textrange = new TextRange(start, end);
// Print the found word to the debug window.
System.Diagnostics.Debug.WriteLine(textrange.Text);
// Select the found word
rtb.Selection.Select(start, end);
}
rtb.Focus();
}
private void rtb_PreviewMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
GetCurrentWord();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
GetCurrentWord();
}