WPF:获取子UIElement在其父级中的位置。忽略RenderTransform(如果有)

时间:2011-01-21 15:05:17

标签: .net wpf controls panel rendertransform

假设我有这个XAML代码:

<DockPanel Name="pan">
    <Label Content="AAA" Name="lab1" />
    <Label Content="BBB" Name="lab2" />
    <Label Content="CCC" Name="lab3" />
</DockPanel>

我的代码背后我想知道lab2pan的坐标是什么。 Hovewer 我想忽略lab2的任何现有RenderTransform。所以解决方案必须为上面的代码返回相同的坐标,然后:

<DockPanel>
    <Label Content="AAA" />
    <Label Content="BBB" >
        <Label.RenderTransform>
            <TranslateTransform Y="20"/>
        </Label.RenderTransform>
    </Label>
    <Label Content="CCC" />
</DockPanel>

换句话说,我希望在ArrangeOverride上调用panArrange的{​​{1}}方法设置的位置。我称之为“合乎逻辑的位置”。可以通过调用以下方法获得“视觉位置”:

but2

但这不是我的问题的解决方案,因为此private Point visualPoss() { Point lab2Vis = lab2.PointToScreen(new Point(0, 0)); Point panVis = pan.PointToScreen(new Point(0, 0)); return new Point(lab2Vis.X - panVis.X, lab2Vis.Y - panVis.Y); } 的返回值对于上面的两个XAML代码示例都不相等。

如果不清楚,请发表评论。

谢谢

2 个答案:

答案 0 :(得分:6)

看起来有一个非常简单明了的解决方案:

private Point logicalPoss() {
    Vector vec = VisualTreeHelper.GetOffset(lab2);
    return new Point(vec.X, vec.Y);
}

看起来效果很好。如果你知道它不起作用的情况,请发表评论。

答案 1 :(得分:3)

我会得到转换,并将其转换为MatrixTransform。然后,您可以使用Inverse属性来反转渲染变换。它看起来像这样:

private Point visualPoss() 
{
    Point lab2Vis = lab2.PointToScreen(new Point(0, 0));
    Point panVis = pan.PointToScreen(new Point(0, 0));

    if (lab2.RenderTransform != null)
    {
        var matrix = new MatrixTransform(lab2.RenderTransform.Value);
        lab2Vis = matrix.Inverse.Transform(lab2Vis);
    }

    return new Point(lab2Vis.X - panVis.X, lab2Vis.Y - panVis.Y);
}