Отримати абсолютну позицію елемента у вікні у wpf


88

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

Відповіді:


127

Я думаю, що BrandonS хоче не позиції миші щодо кореневого елемента, а позиції якогось нащадного елемента.

Для цього існує метод TransformToAncestor :

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

Де myVisualзнаходиться елемент, на який було щойно клацнуто подвійним клацанням, а rootVisualце Application.Current.MainWindow або будь-яка інша позиція, щодо якої ви хочете.


2
Привіт, я спробував це, і я отримую наступний виняток: System.InvalidOperationException не оброблявся Повідомлення = Вказаний Visual не є родоначальником цього Visual. Джерело = PresentationCore Будь-яка ідея?
RoflcoptrException

8
Visual.TransformToAncestor буде працювати лише в тому випадку, якщо ви перейдете до вмісту Visual. Якщо вам потрібно відносне розташування двох елементів, а один не містить іншого, замість цього можна використовувати Visual.TransformToVisual.
Роберт Макні,

5
TransformToVisual все ще вимагає спільного предка, що може бути проблематичним, якщо контроль знаходиться у спливаючому вікні
Адам Міллс,

1
Супер інтуїтивно! Чи не можуть вони обернути це у виклик "GetRelativePosition"? :-) Дякую за допомогу. +1
Павло,

1
@ cod3monk3y - або, можливо, якщо Microsoft з відкритими джерелами WPF, я надішлю їм запит на витяг :-)
Павло

42

Щоб отримати абсолютне положення елемента інтерфейсу у вікні, ви можете використовувати:

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;

4
Зауважте, що це, мабуть, не робить того, що ви очікуєте, якщо масштаб вашого дисплея не встановлений на 100% (тобто на екранах із високим DPI).
Дрю Ноукс

18

Додайте цей метод до статичного класу:

 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розміщення у верхньому лівому кутку вікна програми.


1
Це працює фантастично! Я використовую це з анімацією, яка висуває зображення на екран або за його межі, змінюючи RenderTransformелемент, і тому йому потрібно знати абсолютне положення елемента на екрані.
cod3monk3y

6

З .NET 3.0 ви можете просто використовувати *yourElement*.TranslatePoint(new Point(0, 0), *theContainerOfYourChoice*).

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

Перевірте тут документ.


0

Хм Ви повинні вказати вікно, яке ви натиснули в « Mouse.GetPosition(IInputElement relativeTo) Наступний код», для мене добре працює

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

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


Незважаючи на те, що це не те, про що автор просив, це
допомогло мені досягти
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.