none
Metro Text显示问题 RRS feed

  • 问题

  • 需要在画布上显示一行文字。如ABC,需要定位到B这个位置,显示一张图片。请问如何取得B这个字符的位置。

    2012年6月18日 8:06

答案

  • 首先我想确认,你的ABC是一个TextBlock 还是分开的。 不管怎么样,分开也好,连在一起也好,我们都需要先通过HitTest来获取你的TextBlock的位置:

            private void Canvas_PointerMoved_1(object sender, PointerRoutedEventArgs e)
            {
                var elements = VisualTreeHelper.FindElementsInHostCoordinates(e.GetCurrentPoint(sender as Canvas).Position, sender as Canvas);
                foreach (var element in elements)
                {
                    if (element is TextBlock)
                    {
                        TextBlock txt = element as TextBlock;
                        ...
                    }
                }
            }

    但是对于连在一起的一行字符,要定位其中某个字符,需要知道这个字符在字符串中的索引位置,以及前后每个字符的宽高,然后计算出这个字符的位移,否则无法定位。我们可以用过字符在Run里面的位置TextPointer类型来获得,完整的代码:

            private void Canvas_PointerMoved_1(object sender, PointerRoutedEventArgs e)
            {
                Point p = e.GetCurrentPoint(sender as Canvas).Position;
                var elements = VisualTreeHelper.FindElementsInHostCoordinates(p, sender as Canvas);
                foreach (var element in elements)
                {
                    if (element is TextBlock)
                    {
                        TextBlock txt = element as TextBlock;
                        Point txtPosition = new Point((double)txt.GetValue(Canvas.LeftProperty), (double)txt.GetValue(Canvas.TopProperty));
                        if (txt.Text.Contains("B"))
                        {
                            if (txt.Inlines.Count != 0)
                            {
                                foreach (Inline inline in txt.Inlines)
                                {
                                    if (inline is Run)
                                    {
                                        Run run = inline as Run;
                                        Rect recta = run.ContentStart.GetPositionAtOffset(run.Text.IndexOf("B"), LogicalDirection.Forward).GetCharacterRect(LogicalDirection.Forward);
                                        Rect rectb = run.ContentStart.GetPositionAtOffset(run.Text.IndexOf("B") + 1, LogicalDirection.Forward).GetCharacterRect(LogicalDirection.Forward);
                                        Rect rect = new Rect(recta.X + txtPosition.X,
                                                             recta.Y + txtPosition.Y,
                                                             rectb.X - recta.X,
                                                             recta.Height);
                                        Debug.WriteLine("({0},{1} {2},{3})", rect.Left, rect.Top, rect.Width, rect.Height);
                                    }
                                }
                            }
                        }
                    }
                }
            }


    注意,得出的字符宽度需要前后两个TextPointer的X相减。


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    • 已标记为答案 whyuan 2012年6月19日 9:58
    2012年6月19日 7:38
    版主