如何通过在 FlowDocument 中单击鼠标来获取 TextPointer
我想获取用户在 FlowDocument 中单击的单词。
我当前正在向文档中的每个 Run 添加一个事件处理程序,并迭代单击的 Run 中的 TextPointers,对每个 Run 调用 GetCharacterRect() 并检查矩形是否包含该点。
然而,当点击发生在长跑即将结束时,这需要> 10秒。
有没有更有效的方法呢?
I would like to get the word that a user has clicked on in a FlowDocument.
I am currently adding an event handler to every Run in the document and iterating through the TextPointers in the Run that was clicked, calling GetCharacterRect() on each one and checking if the rectangle contains the point.
However, when the click occurs near the end of a long Run this takes > 10 seconds.
Is there any more efficient method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想说最简单的方法是使用自动化接口:
ITextProvider 的使用需要对 UIAutomationProvider 程序集的引用。该程序集不常被引用,因此您可能需要添加它。使用它的一些方法还需要 UIAutomationTypes。
请注意,根据您呈现 FlowDocument 的方式,有许多选项可用于创建自动化对等点:
更新
我尝试过此操作,效果很好,但事实证明从 ITextRangeProvider 转换为 TextPointer 比我预期的要困难。
我将算法封装在扩展方法
ScreenPointToTextPointer
中以方便使用。下面是一个示例,说明如何使用我的扩展方法将鼠标指针之前的所有文本加粗并取消其之后的所有文本的粗体:这是扩展方法的代码:
另请注意示例 MouseMove 方法中使用 PointToScreen获取要传递到扩展方法中的屏幕点。
I'd say the easiest way is to use the Automation interfaces:
The ITextProvider usage requires a reference to the UIAutomationProvider assembly. This assembly is not commonly referenced, so you may need to add it. UIAutomationTypes will also be needed to use some of its methods.
Note that there are many options for creating your automation peer depending on how you are presenting the FlowDocument:
Update
I tried this and it works well, though converting from an ITextRangeProvider to a TextPointer proved more difficult than I expected.
I packaged the algorithm in an extension method
ScreenPointToTextPointer
for easy use. Here is an example of how my extension method can be used to bold all text before the mouse pointer and un-bold all text after it:Here is the code for the extension method:
Also note the use of PointToScreen in the example MouseMove method to get a screen point to pass into the extension method.
如果 FlowDocument 是 RichTextBox 的 FlowDocument,则可以使用 GetPositionFromPoint() 方法来获取 TextPointer。
If the FlowDocument is that of a RichTextBox, you could use the GetPositionFromPoint() method to get the TextPointer.
鼠标单击事件会冒泡到顶部,您只需在文档中挂钩 PreviewMouseLeftButtonUp 并观察事件的发送者/原始来源,您将获得向您发送事件的运行。
然后您可以使用 RangeFromPoint 并使用
PointToScreen 将您的本地鼠标点转换为全局点。
Mouse Click events are bubbled to the top, instead you can simply hook PreviewMouseLeftButtonUp in your document and watch for the sender/original source of the event, you will get the Run that sent you the event.
Then you can RangeFromPoint and you can use,
PointToScreen that will convert your local mouse point to global point.