什么是对FormattedText执行命中测试的好办法?
题
我使用的渲染文本FormattedText
,但没有出现任何方式对渲染输出进行每个字符命中测试。它是只读的,所以我基本上只需要选择,没有编辑。
我会使用RichTextBox
或相似的,但我需要基于控制代码在文本本身嵌入输出文本,所以他们并不总是窝,这使得构建正确的内联元素非常复杂。我也有点担心与解决方案的性能;我有一个大的行数,而新线路通常所附
我已经看了GlyphRun
,看来我可以得到命中测试从它或相关类,但我会重新实现很多的功能,而且好像应该有一个更简单的方法...
有谁知道的一个很好的方式来实现这一点?
解决方案
最好的办法是设计一个良好的数据结构来存储您的文本,这也认为命中测试。一个例子可以是文本分割成块(也就是说,行或段落取决于你的需要)。然后每个这样的块应该有一个包围盒应在任何格式化操作被重新计算。也可以考虑在设计中插入符号位置。
一旦你有这样的设施就变得非常容易做到的命中测试,只需使用边界框。这也将有助于在后续操作中像高亮文本的特定部分。
其他提示
您可以从一个FormattedText对象的每个字符的几何形状和使用的每个字符的边界做你的命中测试。
var geometry = (GeometryGroup)((GeometryGroup)text.BuildGeometry(new Point(0, 0))).Children[0];
foreach (var c in geometry.Children)
{
if (c.Bounds.Contains(point))
return index;
index++;
}
在的OnRender可以渲染这些几何对象,而不是格式的文本。
完全Sesh同意 - 最简单的方法你要逃脱不重新实现的FormattedText功能的整个负载将会通过拆分单个项目是你想打,考不上自己的控制/内联。
考虑使用一个TextBlock并添加每个单词,因为它是自己的内联(或),那么无论是结合于一字形的IsMouseDirectlyOver属性,我们的添加委托给的MouseEnter&鼠标离开事件。
如果你想要做的实际字形的像素级的点击测试(即是鼠标正是在这个“我”点),那么你就需要使用GlyphRuns并做字形手动点击测试(读:实干)
我非常迟到了 - 如果当事人没有结束,你不需要实际的字符的几何形状,我发现这样的有用:
for (int i = 0; i < FormattedText.Text.Length; i++)
{
characterHighlightGeometry = FormattedText.BuildHighlightGeometry(new Point(), i, 1);
CharacterHighlightGeometries.Children.Add(characterHighlightGeometry);
}
BuildGeometry()只包括一个字符的实际路径的几何形状。 BuildHighlightGeometry()生成的所有字符的外部边界 - 包括 空间,所以一个索引到一个空间可以由位于:
foreach (var c in CharacterHighlightGeometries.Children)
{
if (c.Bounds.Contains(centerpoint))
{
q = c;
cpos = index;
break;
}
index++;
}
希望这有助于。