我的目標是像這樣雙擊“ia”的整個部分:

但是,WPF 的默認設定是單獨選擇字串的每個部分:

樣本:
<RichTextBox>
<FlowDocument>
<Paragraph>Reason for contact: i.a.</Paragraph>
</FlowDocument>
</RichTextBox>
從用戶的角度來看,文本中可能會或可能不會涉及格式化以突出顯示關鍵字,而是將其簡化為“ia”。我認為不會涉及任何格式。整個“單詞”可能被格式化,但不像“i”是紅色而“a”是藍色。
到目前為止我發現了什么
我嘗試使用SpellCheck.CustomDictionaries,單詞選擇不受這些影響。
TextEditorMouse 類負責啟動呼叫 IsAtCaretUnitBoundary 的 SetCaretPositionOnMouseEvent 中的選擇以可能檢查單詞邊界,但我無法理解 TextPointer 的魔力。對我來說,似乎沒有辦法解決這個問題,因為它受到私有和內部方法的保護。
我懷疑TextPointer的CaretPosition是通過看通話將向前或向后涉及System.Windows.Documents.TextPointerBase.GetWordRange(System.Windows.Documents.ITextPointer thisPosition, System.Windows.Documents.LogicalDirection direction)4:
System.Windows.Documents.TextPointer selectionStart = rtb.CaretPosition;
while (selectionStart.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text)
{
selectionStart = selectionStart.GetNextContextPosition(LogicalDirection.Backward);
}
System.Windows.Documents.TextPointer selectionEnd = rtb.CaretPosition;
while (selectionEnd.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
{
selectionEnd = selectionEnd.GetNextContextPosition(LogicalDirection.Forward);
}
uj5u.com熱心網友回復:
如果假設分析文本沒有格式,請考慮使用以下代碼:
private void Rtb_PreviewMouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var tr = GetWordByDelimiters();
// Color the selected text
tr.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.Yellow);
rtb.Focus();
e.Handled = true;
}
public TextRange GetWordByDelimiters()
{
TextPointer current = rtb.CaretPosition;
// \s matches any whitespace character (equivalent to [\r\n\t\f\v ])
string pattern = @"[^\s] "; // Delimiters
// The run content before the current caret position
string backward = current.GetTextInRun(LogicalDirection.Backward);
// Scan text before caret
Match match = Regex.Match(backward, pattern, RegexOptions.RightToLeft);
TextPointer start = current;
if (match.Success && match.Index match.Value.Length == backward.Length)
{
start = start.GetPositionAtOffset(-backward.Length match.Index);
}
// The run content after the current caret position
string forward = current.GetTextInRun(LogicalDirection.Forward);
// Scan text after caret
match = Regex.Match(forward, pattern);
TextPointer end = current;
if (match.Success && match.Index == 0)
{
end = end.GetPositionAtOffset(match.Value.Length, LogicalDirection.Forward);
}
return new TextRange(start, end);
}
的片段.xaml:
<RichTextBox x:Name="rtb" AllowDrop="True" VerticalScrollBarVisibility="Auto"
PreviewMouseDoubleClick="Rtb_PreviewMouseDoubleClick">
<FlowDocument>
...
</FlowDocument>
</RichTextBox>
如果有必要修改pattern以使用任何一組分隔符。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/360013.html
