如何在光标移过FlowDocumentPageViewer时捕获光标后方的单词
FlowDocumentPageViewer光标下单词捕获实现方案
实现该功能的核心逻辑是通过鼠标坐标命中测试拿到文档内对应位置的文本指针,再按单词边界扩展提取完整单词,具体步骤如下:
- 第一步:给目标
FlowDocumentPageViewer控件绑定MouseMove事件,同时确保控件的IsHitTestVisible属性为True,如果文档内容需要交互也可以开启IsDocumentEnabled属性。 - 第二步:在MouseMove事件回调中,先获取鼠标相对于控件的坐标,再通过命中测试获取光标下的文本指针:
Point mousePosition = e.GetPosition(yourFlowDocumentPageViewer); HitTestResult hitResult = VisualTreeHelper.HitTest(yourFlowDocumentPageViewer, mousePosition); if (hitResult?.VisualHit is Run run) { // 获取光标在当前Run元素内的字符偏移 int offset = run.GetPositionFromPoint(mousePosition, true).OffsetTo(run.ContentStart); TextPointer currentPointer = run.ContentStart.GetPositionAtOffset(offset); if (currentPointer == null) return; } - 第三步:从当前文本指针向前后遍历,提取完整单词。可以自定义单词的判定规则,比如英文场景下判定字符是否为字母/数字/连接符,中文场景下可调整为按中文字符、标点分隔:
上面用到的// 向前查找单词起始位置 TextPointer wordStart = currentPointer; while (wordStart != null && IsWordCharacter(wordStart.GetPointerContext(LogicalDirection.Backward))) { wordStart = wordStart.GetNextContextPosition(LogicalDirection.Backward); } // 向后查找单词结束位置 TextPointer wordEnd = currentPointer; while (wordEnd != null && IsWordCharacter(wordEnd.GetPointerContext(LogicalDirection.Forward))) { wordEnd = wordEnd.GetNextContextPosition(LogicalDirection.Forward); } // 提取单词文本 if (wordStart != null && wordEnd != null) { string targetWord = new TextRange(wordStart, wordEnd).Text; // 此处可自定义单词的后续处理逻辑 }IsWordCharacter是自定义判定方法,示例实现如下:private bool IsWordCharacter(TextPointerContext context) { if (context != TextPointerContext.Text) return false; char c = context.GetTextInRun(LogicalDirection.Forward)[0]; // 可根据需求调整判定规则,比如加入中文、下划线、连字符等支持 return char.IsLetterOrDigit(c) || c == '_'; }
注意:如果你的FlowDocument包含非文本内嵌元素(图片、按钮、表格等),需要在命中测试时过滤掉这些元素的返回结果,避免出现指针获取失败的问题。
内容的提问来源于stack exchange,提问作者TheDeparted
相关产品推荐
相关产品推荐

