TransformToVisual方法无法正常用于动态控件

时间:2012-05-28 10:15:14

标签: c# silverlight transformtovisual

我正在尝试使用以下代码行通过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

2 个答案:

答案 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做了很多相同的事情,它“推”了要完成的新工作,导致队列中的任何等待工作(布局更新)首先被处理。