代码之家  ›  专栏  ›  技术社区  ›  Eric

对格式化文本执行命中测试的好方法是什么?

  •  1
  • Eric  · 技术社区  · 15 年前

    我正在使用 FormattedText

    我会用 RichTextBox 或者类似的,但是我需要根据嵌入文本本身的控制代码输出文本,所以它们不总是嵌套,这使得构建正确的内联元素非常复杂。我也有点担心该解决方案的性能;我有大量的行,并且经常追加新行。

    GlyphRun ,似乎我可以从它或相关类中获得命中测试,但我将重新实现许多功能,而且似乎应该有一种更简单的方法。。。

    有人知道一个很好的方法来实现这一点吗?

    4 回复  |  直到 13 年前
        1
  •  4
  •   justin.m.chase    13 年前

    您可以从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中,可以渲染这些几何体对象,而不是格式化文本。

        2
  •  3
  •   Sesh    15 年前

    最好的方法是设计一个良好的数据结构来存储文本,同时考虑命中测试。一个例子是将文本分割成块(单词、行或段落,取决于您需要什么)。然后,每个这样的块都应该有一个边界框,在任何格式化操作中都应该重新计算该边界框。还要考虑你的设计中的插入位置。

        3
  •  1
  •   Mark    15 年前

    完全同意Sesh-不重新实现全部FormattedText功能的最简单方法是将要进行测试的单个项拆分为它们自己的控件/内联线。

    考虑使用文本块并将每个单词作为自己的内联(或)添加,然后绑定到内联的ISMouSeDistTyLyFor属性,将我们的添加委托给鼠标器和AMP;鼠标移动事件。

    如果要对实际图示符进行像素级命中测试(即鼠标是否正好位于该“i”的点上),则需要使用图示符运行并对图示符进行手动命中测试(阅读:艰苦工作)。

        4
  •  1
  •   Alan Wayne    10 年前

    我去派对已经很晚了——如果派对还没有结束,你不需要实际的角色几何,我发现这样的东西很有用:

     for (int i = 0; i < FormattedText.Text.Length; i++)
     {
                characterHighlightGeometry = FormattedText.BuildHighlightGeometry(new Point(), i, 1);
                CharacterHighlightGeometries.Children.Add(characterHighlightGeometry);
     }
    

    空间,因此可以通过以下方式找到空间的索引:

     foreach (var c in CharacterHighlightGeometries.Children)
            {
                if (c.Bounds.Contains(centerpoint))
                {
                    q = c;
                    cpos = index;
                    break;
                }
                index++;
            }
    

    希望这有帮助。