zoukankan      html  css  js  c++  java
  • WPF TextSelection获取选中部分内容

    一、简单实例

    //TextSelect继承自TextRange
    TextSelection selection = richTextBox.Selection;
    //1.获取选中内容
    string result = selection.Text;
    MessageBox.Show(result);

    二、内容转自:WPF: 从TextSelection中获取Inline并且考虑部分选择的Run

    FlowDocument的容器,比如RichTextBox,FlowDocumentReader,FlowDocumentPageViewer或者FlowDocumentScrollViewer类型都有一个Selection属性表示选择的区域。这个Selection属性就是一个TextSelection对象,继承自TextRange类型,这里很不爽的地方是当你想从这个TextSelection对象中获取选择区域的具体内容时,它只有一个Text属性,返回一个字符串,就是把所有选择区域的字符串提取出来,注意这个字符串不是纯文本的字符串,也可能是包含图片的RTF字符串,那么如果有用户自定义的InlineUIContainer控件什么的,完全被忽略。看了.NET内部的源代码,发现这里真的实现的很不好,具体可以参考内部类型TextRangeBase里的internal static string GetTextInternal(ITextPointer startPosition, ITextPointer endPosition, ref char[] charArray)方法,如下图:

    image

    代码逻辑是当遇到自定义UI对象时,直接加一个空格就完事了,简直可以用坑爹来形容,不能给InlineUIContainer加个接口什么的返回个有用的字符串吗?

    为了解决问题,我们只能借助自己的方式来Selection中所有的Inline信息,来看示例程序,在FlowDocumentScrollViewer中选中一些内容:

    image

    输出:

    image

    OK!可以获取具体InlineUIContainer的信息,同时被部分选择的Run里的信息也被正确提取出来。

    具体实现是这样的,首先枚举FlowDocument中的所有Inline(这里有再优化的余地,比如搞个类似折半查找的策略会更高效),然后通过TextRange的Contains方法,判断Inline的ContentStart和ContentEnd是否包含在TextRange中,这两个属性返回具体的TextPointer对象。这两个判断出结果后,执行下面的策略:

    完全包含
      处理Inline

    部分包含
      如果Inline是Run,考虑Run从开头或者结尾被部分选择的情况

    完全不包含
      如果Inline是Run,考虑Run中间被部分选择的情况

    需要注意的地方:

    1. TextPointer自己有CompareTo方法可以判断2个TextPointer的大小,这里可以判断出完全不包含的情况(每个TextElement对象都有位置属性返回TextPointer)。

    2. “考虑Run从开头或者结尾被部分选择的情况”时可以通过TextPointer的GetTextInRun方法传入一个LogicalDirection枚举返回对应方向的部分选择字符串。

    3. “考虑Run中间被部分选择的情况”时直接通过TextRange的Text属性就可以把字符串提取出来。

     

  • 相关阅读:
    诡异的命名空间问题
    如何为自定义属性提供表达式绑定支持
    为SSIS编写自定义数据流组件(DataFlow Component)之进阶篇:自定义编辑器
    SSAS : 外围应用配置器
    SSAS : 数据访问接口整理汇总
    SSAS : ADOMDConnection.ConnectionString的参数列表
    SSIS中的字符映射表转换组件
    SSAS: Discover 何处寻? 一切尽在GetSchemaDataSet
    为SSIS编写简单的同步转换组件
    如何在同步转换组件中增加输出列
  • 原文地址:https://www.cnblogs.com/tianma3798/p/5929298.html
Copyright © 2011-2022 走看看