繁体   English   中英

如何使用现有内容格式化RichTextBox

[英]How to format a RichTextBox with existing contents

我从Web API获取数据,返回文本和格式信息。 格式化数据仅包括格式类型(粗体,斜体等)以及格式化的范围。 这个问题的主要问题是,两个范围可以“碰撞”(例如,单词的前3个字符是粗体和斜体,但最后3个字符只是斜体)。 响应示例

{
  "text" : "This is an example text",
  "inlineStyles" : [
    {
      "offsetFromStart" : 5,
      "length" : 10,
      "type" : "bold"
    }
    {
      "offsetFromStart" : 10,
      "length" : 10,
      "type" : "italic"
    }
  ]
}

我已经尝试使用简单的TextBlock执行此操作并失败。 我也尝试使用RichTextBox,但是当我添加了Span时,我无法将其插入原始位置。 我还试图用自己的跨度或运行格式化每个角色,但这将是非常丑陋的,通常只是一个糟糕的解决方案。 (我主要担心的是速度..)

var tb = new RichTextBox();
var para = new Paragraph();
para.Inlines.Add("This is an example text") // Text parsed from the response

var startingPointer1 = para.ContentStart.GetPositionAtOffset(5);
var sp1 = new Span(startingPointer1, startingPointer1.GetPositionAtOffset(10));
sp1.FontWeight = FontWeights.Bold;

var startingPointer2 = para.ContentStart.GetPositionAtOffset(10);
var sp2 = new Span(startingPointer2 , startingPointer2 .GetPositionAtOffset(10));
sp2.FontStyle= FontStyles.Italic;

para.Inlines.Add(sp1);
para.Inlines.Add(sp2);
tb.Document.Blocks.Add(para);

这段代码将它追加到最后,当组合多个内联元素时,就像我的例子中一样,它根本不起作用(因为第一个问题。)

示例结果: 示例图片

我不认为你可以像这样重叠运行/跨度,你必须找到文本中的所有断点并分别格式化每个文本范围。 它类似于HTML,其中

<bold>some<italic> bold italic</bold> and other </italic> text.

无效。 在你的情况下,你将从(5,10)粗体,(11,15)等粗体。

找到某种Range类并使用方法来组合范围,拆分,查找重叠等可能很有用。前段时间我开始使用

编辑:我不知道如何实现所有这些(上次我做了类似的事情差不多10年前),但你可以尝试这样的事情:

  1. 创建一个List<Range<int>> 最初它包含一个Range(0,文本长度)。
  2. 加载第一个样式,创建一个带有开始/结束偏移的新范围。 重叠(或任何适当的方法)此范围与列表中的范围。 这应该给你3个范围,比如(0, start of style), (start of style, end of style), (end of style, end of text) 从列表中删除旧范围并添加新范围。
  3. 加载下一个,找到重叠,列表中的范围,删除重叠的那些并添加新范围。
  4. 这应该给你一个非重叠范​​围的列表。
  5. 现在,对于风格。 您可以创建一种样式表类。 此类可以使用System.Windows定义的FontWeights, FontStyles和其他枚举。 修改列表,使其包含,例如, List<Tuple<int, Stylesheet>> 要计算重叠,只需使用元组中的第一个参数。
  6. 在从列表中删除旧范围之前,请合并样式。
  7. 这应该为您提供具有适当样式的非重叠区域列表。 创建TextRange ,应用样式

其他可能有用的想法:

  1. 再次,创建一个样式表。 最初它应该是正常的重量,正常的样式,默认的字体大小等。
  2. 从输入中找到下一个偏移量(第一个大于当前值的偏移量),创建TextRange并应用样式。
  3. 从输入中查找下一个偏移量,修改当前(且仅限)样式并应用。

如果我没记错的话,在文本中插入样式定义也会计为字符,因此在最终文本中插入样式标记时可能需要调整偏移量。 另外,我相信只使用TextBlock是可行的。

正如我所说,我不知道这是否如所述,但这可能会给你和想法。

我目前的解决方案是逐个浏览每个字符并扫描范围,检测当前字符是否在其中任何字符中,然后为字符分配跨度。 这根本理想,但它完成了工作。 我稍后会尝试为此实现一个实际的算法。 在此之前,如果您有任何可以提供帮助的信息,请发表评论。

如果有人需要我当前实现的示例代码,我很乐意与您分享。 (尽管它根本没有效率)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM