[英]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年前),但你可以尝试这样的事情:
List<Range<int>>
。 最初它包含一个Range(0,文本长度)。 (0, start of style), (start of style, end of style), (end of style, end of text)
。 从列表中删除旧范围并添加新范围。 System.Windows
定义的FontWeights, FontStyles
和其他枚举。 修改列表,使其包含,例如, List<Tuple<int, Stylesheet>>
。 要计算重叠,只需使用元组中的第一个参数。 TextRange
,应用样式 其他可能有用的想法:
TextRange
并应用样式。 如果我没记错的话,在文本中插入样式定义也会计为字符,因此在最终文本中插入样式标记时可能需要调整偏移量。 另外,我相信只使用TextBlock
是可行的。
正如我所说,我不知道这是否如所述,但这可能会给你和想法。
我目前的解决方案是逐个浏览每个字符并扫描范围,检测当前字符是否在其中任何字符中,然后为字符分配跨度。 这根本不理想,但它完成了工作。 我稍后会尝试为此实现一个实际的算法。 在此之前,如果您有任何可以提供帮助的信息,请发表评论。
如果有人需要我当前实现的示例代码,我很乐意与您分享。 (尽管它根本没有效率)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.