Получить абсолютную позицию элемента в окне в wpf

Я хотел бы получить абсолютную позицию элемента по отношению к оконному / корневому элементу при двойном щелчке. Относительное положение элемента в его родительском элементе - это все, что мне кажется, и я пытаюсь добраться до точки относительно окна. Я видел решения, как получить точку элемента на экране, но не в окне.


person BrandonS    schedule 22.12.2008    source источник


Ответы (5)


Я думаю, что BrandonS хочет не положение мыши относительно корневого элемента, а скорее положение некоторого дочернего элемента.

Для этого есть TransformToAncestor метод:

Point relativePoint = myVisual.TransformToAncestor(rootVisual)
                              .Transform(new Point(0, 0));

Где myVisual - это элемент, по которому только что дважды щелкнули, а rootVisual - это Application.Current.MainWindow или любое другое положение, относительно которого вы хотите.

person Robert Macnee    schedule 22.12.2008
comment
Привет, я попробовал это и получил следующее исключение: System.InvalidOperationException не было обработано Сообщение = Указанный визуал не является предком этого визуала. Источник = PresentationCore Есть идеи? - person RoflcoptrException; 28.10.2010
comment
Visual.TransformToAncestor будет работать, только если вы передадите содержащий Visual. Если вам нужно относительное положение двух элементов, и один из них не содержит другого, вы можете вместо этого использовать Visual.TransformToVisual. - person Robert Macnee; 01.11.2010
comment
TransformToVisual по-прежнему требует общего предка, что может быть проблематичным, если элемент управления находится во всплывающем окне. - person Adam Mills; 21.11.2011
comment
Супер интуитивно понятно! Разве они не могут обернуть это в вызов GetRelativePosition? :-) Спасибо за помощь. +1 - person Paul; 09.10.2012
comment
@Paul - Попробуйте написать метод расширения! - person cod3monk3y; 04.02.2015
comment
@ cod3monk3y - или, может быть, если Microsoft откроет исходный код WPF, я пришлю им запрос на перенос :-) - person Paul; 04.02.2015

Чтобы получить абсолютное положение элемента пользовательского интерфейса в окне, вы можете использовать:

Point position = desiredElement.PointToScreen(new Point(0d, 0d));

Если вы находитесь в пользовательском элементе управления и просто хотите относительное положение элемента пользовательского интерфейса в этом элементе управления, просто используйте:

Point position = desiredElement.PointToScreen(new Point(0d, 0d)),
controlPosition = this.PointToScreen(new Point(0d, 0d));

position.X -= controlPosition.X;
position.Y -= controlPosition.Y;
person Filip    schedule 21.03.2013
comment
Обратите внимание, что это, вероятно, не будет делать то, что вы ожидаете, если масштаб вашего дисплея не установлен на 100% (то есть на экранах с высоким разрешением). - person Drew Noakes; 07.04.2016

Добавьте этот метод в статический класс:

 public static Rect GetAbsolutePlacement(this FrameworkElement element, bool relativeToScreen = false)
    {
        var absolutePos = element.PointToScreen(new System.Windows.Point(0, 0));
        if (relativeToScreen)
        {
            return new Rect(absolutePos.X, absolutePos.Y, element.ActualWidth, element.ActualHeight);
        }
        var posMW = Application.Current.MainWindow.PointToScreen(new System.Windows.Point(0, 0));
        absolutePos = new System.Windows.Point(absolutePos.X - posMW.X, absolutePos.Y - posMW.Y);
        return new Rect(absolutePos.X, absolutePos.Y, element.ActualWidth, element.ActualHeight);
    }

Установите параметр relativeToScreen на true для размещения из верхнего левого угла всего экрана или на false для размещения из верхнего левого угла окна приложения.

person Andreas    schedule 28.01.2014
comment
Это потрясающе работает! Я использую это с анимацией, которая перемещает изображение на экран или за пределы экрана, изменяя RenderTransform элемента, и поэтому ему необходимо знать абсолютное положение элемента на экране. - person cod3monk3y; 05.02.2015

Начиная с .NET 3.0, вы можете просто использовать *yourElement*.TranslatePoint(new Point(0, 0), *theContainerOfYourChoice*).

Это даст вам точку 0, 0 вашей кнопки, но в сторону контейнера. (Вы также можете указать другой балл, что 0, 0)

Здесь можно найти документ.

person Guibi    schedule 22.07.2018

Хм. Вы должны указать окно, в котором вы щелкнули Mouse.GetPosition(IInputElement relativeTo) Следующий код мне подходит

protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        Point p = e.GetPosition(this);
    }

Я подозреваю, что вам нужно обращаться к окну не из его собственного класса, а из другой точки приложения. В этом случае вам поможет Application.Current.MainWindow.

person Oleg    schedule 22.12.2008
comment
Несмотря на то, что это не то, о чем просил автор, я на правильном пути, спасибо - person Ladislav Ondris; 25.02.2019