TransformToVisual 方法对于动态控件无法正常工作

本文关键字:常工作 工作 方法 动态控件 TransformToVisual | 更新日期: 2023-09-27 18:35:34

我试图使用以下代码行通过TransformToVisual方法获取用户控件的位置:

this.TransformToVisual(ParentElement).Transform(new Point());

如果控件是在 XAML 中定义的,则坐标正常。但是现在我想像这样动态定义控件:

stackPanel.Children.Add(new Control());

坐标将移动,TransformToVisual 方法将忽略边距并对齐(返回堆栈面板的左上角)。

XAML 层次结构如下所示:

<Grid x:Name="ParentElement">
    <StackPanel>
        <StackPanel>
            <Border>
                <StackPanel>
                    <TextBlock  />
                    <StackPanel x:Name="stackPanel" />
                </StackPanel>
            </Border>
        </StackPanel>
    </StackPanel>
</Grid>

所以我的问题是:有没有办法再次正确获取坐标?

谢谢,奎蒂

TransformToVisual 方法对于动态控件无法正常工作

我能够自己解决问题:

如果我在调用 TransformToVisual() 之前调用 UpdateLayout() 方法,坐标不再坏。实际宽度和高度属性还有其他一些小问题,它们以零形式返回。我通过在 Dispatcher.BeginInvoke delegate 中调用这些属性来修复此问题。

我想

添加一些东西,因为我遇到了一个非常相似的问题,这给我带来了一段时间的问题。当我在适用于 Windows 8.1 的 WinRT 中的 UI 上访问调度程序时,我找不到 BeginInvoke 方法,因此无法尝试您列出的解决方案。

经过一些测试,我认为我问题的根本原因是更改 UI 的布局,然后在系统有时间正确更新布局之前调用 TransformToVisual。这可能是您上面提到的相同问题。我发现在布局未受影响的 UI 部分上运行 TransformToVisual 会返回正确的结果,只有针对存在问题的地方更新布局的 UI 部分。

似乎当布局被更改以使TransformToVisual正常工作时,UI必须有机会对布局更新做出"反应"。就我而言,我正在更改布局,然后在调用 TransformToVisual 后立即更改(在 Tap 事件处理程序中,一行紧接着另一行)。由于这些调用都采用相同的方法,因此 UI 可能无法在更新布局和调用 TransformToVisual 之间处理任何新消息(我假设布局更新作为消息推送到 UI 处理循环中)。如果我将TransformToVisual移动到MouseUp事件中(当时我使用的是鼠标),那么一切正常。可能在您的情况下调用 BeginInvoke 做了同样的事情,它"推送"要完成的新工作,这导致队列中的任何等待工作(布局更新)首先被处理。