首页 > 解决方案 > 在 UWP 下,GetRectFromCharacterIndex 不返回调整为控件样式的值

问题描述

GetRectFromCharacterIndexUWP(与 WPF 相对)中使用时,结果是相对于可以输入文本的位置的绝对偏移量,而不是在控件内部。

例如,以下 XAML:

<TextBox x:Name="noPadding" Margin="0,0,0,20" Text="aaa"/>

当您调用 时,在 UWP 和 WPF 上GetRectFromCharacterIndex(0)返回不同的值。Rect.Left

WPF:Rect.Left == 3 UWP:Rect.Left == 0

当您重新设置样式或控件的外观时,差异变得更加明显:

<TextBox x:Name="withPadding" Padding="60,0,0,0" Margin="0,0,0,20" Text="aaa"/>

WPF:Rect.Left == 63 UWP:Rect.Left == 0

如何获取控件上角色的实际位置?

注意:我知道我可以通过计算 TextBox 内的 TextView 的位置来破解它。但我试图了解支持的执行方式是什么。

标签: c#xamluwpuwp-xaml

解决方案


因此,鉴于尚未得到适当的支持,这就是我解决它的方法(如果有人找到“支持”的解决方案,我将取消标记我的答案并标记那个)

这种扩展方法似乎可以解决问题:

    public static Rect GetRelativeRectFromCharacterIndex(this TextBox textBox, int charIndex, bool trailingEdge)
    {
        var caret = textBox.GetRectFromCharacterIndex(charIndex, trailingEdge);

        // Hack: UWP does not properly return the location compared to the control, so we need to calculate it.
        // https://stackoverflow.com/questions/50304918/under-uwp-getrectfromcharacterindex-does-not-return-values-adjusted-to-the-styl
        var scroller = textBox.GetDescendants().OfType<ScrollContentPresenter>().FirstOrDefault();
        var transform = scroller.TransformToVisual(textBox);
        transform.TryTransform(new Point(caret.Left, caret.Top), out var topLeft);
        transform.TryTransform(new Point(caret.Right, caret.Bottom), out var bottomRight);

        caret = new Rect(topLeft, bottomRight);
        return caret;
    }

然后,您需要 GetDescendants():

    public static IEnumerable<DependencyObject> GetDescendants(this DependencyObject container)
    {
        var stack = new Stack<DependencyObject>();
        stack.Push(container);

        while (stack.Count > 0)
        {
            var item = stack.Pop();
            var count = VisualTreeHelper.GetChildrenCount(item);
            for (int i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(item, i);
                yield return child;
                stack.Push(child);
            }
        }
    }

推荐阅读