c# - 在 UWP 下,GetRectFromCharacterIndex 不返回调整为控件样式的值
问题描述
在GetRectFromCharacterIndex
UWP(与 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 的位置来破解它。但我试图了解支持的执行方式是什么。
解决方案
因此,鉴于尚未得到适当的支持,这就是我解决它的方法(如果有人找到“支持”的解决方案,我将取消标记我的答案并标记那个)
这种扩展方法似乎可以解决问题:
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);
}
}
}
推荐阅读
- mongodb - mongodb 身份验证和连接字符串如何工作?
- javascript - 将日期和时间变量传递到另一个 php 页面时出现问题
- javascript - 将 Array of items 推入 Array of stores,它位于 StoreType 的 Array 下
- android - android.view.WindowLeaked: 因为这个 dialog.getWindow.setBackgroundDrawableResource
- java - 使用 PBEFileProcessor 解密 bouncycastle 提供的文件
- c# - 重命名目录中的现有条目会出现“命名违规”错误
- javascript - 如何计算Javascript中多个动态输入字段的总和?
- amazon-web-services - 用于 DynamoDB LeadingKeys 限制的 IAM 策略 Cognito 变量
- bash - add answer to first commands question in shell script
- php - 当多个输入具有相同名称时,根据输入类型设置 jquery 表单验证