我正在尝试使用以下代码行通过TransformToVisual方法获取用户控件的位置:
this.TransformToVisual(ParentElement).Transform(new Point());
如果控件是在XAML中定义的,则坐标是正确的。但是现在我想像这样动态地定义控件:
stackPanel.Children.Add(new Control());
坐标移位,TransformToVisual方法忽略边距并对齐(返回stackpanel的左上角)。
XAML层次结构如下:
<Grid x:Name="ParentElement">
<StackPanel>
<StackPanel>
<Border>
<StackPanel>
<TextBlock />
<StackPanel x:Name="stackPanel" />
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
</Grid>
所以我的问题是:有没有办法再次正确地获得坐标?
谢谢,kwitee
答案 0 :(得分:1)
我能够自己修复这个问题:
如果在调用TransformToVisual()之前调用UpdateLayout()方法,则坐标不再是坏的。 ActualWidth和height属性还有一些其他小问题,它们以零的形式返回。我通过在Dispatcher.BeginInvoke委托中调用这些属性来修复它。
答案 1 :(得分:1)
我想添加一些内容,因为我遇到了一个非常类似的问题,这对我来说有一段时间了。当我在WinRT for Windows 8.1中访问UIElement上的Dispatcher时,我无法找到BeginInvoke方法,因此我无法尝试您列出的解决方案。
经过一些测试后我认为我的问题的根本原因是改变了UI的布局,然后在系统有时间正确更新布局之前调用了TransformToVisual。这可能与您上面提到的问题相同。我发现在未受其布局影响的UI部分上运行TransformToVisual会返回正确的结果,只有UI的部分才会在问题存在的地方更新布局。
似乎在更改布局以使TransformToVisual正常工作时,UI必须有机会对布局更新做出“反应”。在我的情况下,我正在改变布局,然后在调用TransformToVisual之后立即(在Tapped事件处理程序中一个接着一行)。由于这些调用都在同一个方法中,因此UI可能无法在更新布局和调用TransformToVisual之间处理任何新消息(我假设布局更新在UI处理循环中作为消息被推送) 。如果我将TransformToVisual移动到MouseUp事件(我当时正在使用鼠标),那么一切正常。可能在你的情况下调用BeginInvoke做了很多相同的事情,它“推”了要完成的新工作,导致队列中的任何等待工作(布局更新)首先被处理。