WPF: получить позицию дочернего элемента UIElement в родительском элементе.Игнорировать RenderTransform, если есть - PullRequest
4 голосов
/ 21 января 2011

Допустим, у меня есть этот код XAML:

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

Я поставил свой код и хочу узнать, каковы координаты lab2 в пределах pan. Hovewer Я хочу игнорировать любой существующий RenderTransform lab2. Таким образом, решение должно возвращать те же координаты для вышеуказанного кода и следующего:

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

Другими словами, мне нужна позиция, которая была установлена ​​методом ArrangeOverride для pan при вызове Arrange на 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);
} 

Но это не решение моей проблемы, поскольку возвращаемое значение этого visualPoss() не равно для обоих приведенных выше примеров кода XAML.

Пожалуйста, оставьте комментарий, если что-то неясно.

Спасибо

Ответы [ 2 ]

6 голосов
/ 21 января 2011

Похоже, есть очень простое и понятное решение:

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

Похоже, что оно работает хорошо.Если вы знаете, что Scenerio не работает, оставьте комментарий.

3 голосов
/ 21 января 2011

Я бы получил преобразование и преобразовал бы его в 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);
} 
...