在 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/