c# - 在 UWP 下,GetRectFromCharacterIndex 不会返回根据控件样式调整的值

标签 c# xaml uwp uwp-xaml

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

例如,以下 XAML:

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

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

WPF:矩形.Left == 3 UWP:矩形.Left == 0

当您重新设计控件的样式或以其他方式更改控件的外观时,差异会变得更加明显:

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

WPF:矩形.Left == 63 UWP:矩形.Left == 0

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

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

最佳答案

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

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

    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);
            }
        }
    }

关于c# - 在 UWP 下,GetRectFromCharacterIndex 不会返回根据控件样式调整的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50304918/

相关文章:

c# - 启用 CORS 的 Web API 无法添加 header

c# - 如何在存储过程中将 DateTime 格式传递给 MS sql server?

wpf - 来自动态资源的 TextBlock 换行符

c# - 如何传播 DependencyProperty 中的 PropertyChanged 更改

windows - Windows 10 UWP(桌面桥)应用程序可以重新启动自己的可执行文件吗?

c# - x :Bind to DependencyProperty not working (classic Binding works fine)

c# - 从 DynamicResource 为 BorderBrush 设置动画会使用该画笔为所有内容设置动画

c# - C#中的命名空间

silverlight - 如何对齐文本,使其位于 Silverlight 中按钮的中间?

c# - 将 StreamReader(String) 转换为与 UWP API 兼容?