c# - 如何使用现有内容格式化 RichTextBox
问题描述
我从返回文本和格式信息的 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);
此代码将其附加到末尾,并且在我的示例中组合多个内联元素时,它根本不起作用(因为第一个问题。)
解决方案
我认为您不能像这样重叠 Runs/Spans,您必须找到文本中的所有断点并分别格式化每个文本范围。它类似于 HTML,其中
<bold>some<italic> bold italic</bold> and other </italic> text.
无效。在您的情况下,您将有一个来自 (5,10) 的粗体,来自 (11, 15) 的粗体等。
找到某种Range
具有组合范围、拆分、查找重叠等方法的类可能很有用。不久前,我从这个开始。
编辑:我不完全知道如何实现所有这些(上次我做了类似的事情差不多是 10 年前),但你可以尝试这样的事情:
- 创建一个
List<Range<int>>
. 最初它包含一个范围(0,文本长度)。 - 加载第一个样式,创建一个带有开始/结束偏移的新范围。将此范围与列表中的范围重叠(或任何适当的方法)。这应该为您提供 3 个范围,例如
(0, start of style), (start of style, end of style), (end of style, end of text)
. 从列表中删除旧范围并添加新范围。 - 加载下一个,查找重叠,与列表中的范围,删除重叠的范围并添加新范围。
- 这应该为您提供一个不重叠范围的列表。
- 现在,对于样式。您可以创建一种样式表类。此类可以使用在
FontWeights, FontStyles
中定义的 和其他枚举System.Windows
。修改一个列表,使其包含例如List<Tuple<int, Stylesheet>>
. 要计算重叠,只需使用元组中的第一个参数。 - 从列表中删除旧范围之前,请组合样式。
- 这应该为您提供具有适当样式的非重叠区域列表。创建
TextRange
,应用样式
其他可能有效的想法:
- 同样,创建一个样式表。最初它应该是正常的重量、正常的样式、默认的字体大小等。
- 找到输入的下一个偏移量(第一个大于当前的偏移量),创建一个
TextRange
并应用一个样式。 - 从输入中找到下一个偏移量,修改当前(也是唯一的)样式并应用。
如果我没记错的话,在文本中插入样式定义也算作字符,因此在最终文本中插入样式标签时可能需要调整偏移量。另外,我相信仅使用TextBlock
.
正如我所说,我不知道这是否像描述的那样工作,但这可能会给你和想法。
推荐阅读
- python - 使用 R 进行切片操作
- hana - 尝试将数据从 NVARCHAR 移动到 HANA 中的 TEXT
- javascript - 使用 Google 表格中的数据填充 html 页面
- android - 如何在 ImageButton 上显示文本?
- google-app-engine - 默认应用程序域未将 URL 更改为分配的自定义域
- java - slf4j+log4j 应用程序如何恢复工作当硬盘已满时
- laravel - 是否可以实现基于字符串的认证
- java - 如何使用 soothscroll 滚动到某些特定的 textview 元素?
- oracle - 如果我必须使用分区子句中未使用的列进行查询,我应该使用 oracle 分区吗
- excel - 编写宏代码后 - 公式给出编译时语法错误。没有宏工作正常