Get Absolute Position of element within the window in wpf
Asked Answered
C

6

103

I would like to get the absolute position of an element in relation to the window/root element when it is double clicked. The element's relative position within it's parent is all I can seem to get to, and what I'm trying to get to is the point relative to the window. I've seen solutions of how to get a the point of an element on the screen, but not in the window.

Citystate answered 22/12, 2008 at 16:57 Comment(0)
N
145

I think what BrandonS wants is not the position of the mouse relative to the root element, but rather the position of some descendant element.

For that, there is the TransformToAncestor method:

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

Where myVisual is the element that was just double-clicked, and rootVisual is Application.Current.MainWindow or whatever you want the position relative to.

Nicki answered 22/12, 2008 at 22:57 Comment(6)
Hi i tried this and i get the following exception: System.InvalidOperationException was unhandled Message=The specified Visual is not an ancestor of this Visual. Source=PresentationCore Any idea?Minify
Visual.TransformToAncestor will only work if you pass in a containing Visual. If you want the relative position of two elements and one doesn't contain the other, you can use Visual.TransformToVisual instead.Nicki
TransformToVisual still requires a common ancestor which can be problematic if the control is in a popupBursar
Super intuitive! Can't they wrap this in a "GetRelativePosition" call? :-) Thanks for the help. +1Alten
@Alten - Try writing an extension method!Lesleelesley
@Lesleelesley - or perhaps, maybe if Microsoft open sources WPF, I'll send them a pull request :-)Alten
W
52

To get the absolute position of an UI element within the window you can use:

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

If you are within a User Control, and simply want relative position of the UI element within that control, simply use:

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

position.X -= controlPosition.X;
position.Y -= controlPosition.Y;
Wortham answered 21/3, 2013 at 0:31 Comment(1)
Note that this probably doesn't do what you expect if your display scaling isn't set to 100% (ie on high DPI screens).Joannejoannes
S
21

Add this method to a static class:

 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);
    }

Set relativeToScreen paramater to true for placement from top left corner of whole screen or to false for placement from top left corner of application window.

Stereogram answered 28/1, 2014 at 16:59 Comment(1)
This works fantastically! I'm using this with an animation that slides an image on- or off-screen by modifying the RenderTransform of the element, and therefore it needs to know the absolute position of the element on the screen.Lesleelesley
J
10

Since .NET 3.0, you can simply use *yourElement*.TranslatePoint(new Point(0, 0), *theContainerOfYourChoice*).

This will give you the point 0, 0 of your button, but towards the container. (You can also give an other point that 0, 0)

Check here for the doc.

Jaggery answered 22/7, 2018 at 11:44 Comment(0)
S
0
childObj.MouseDown += (object sender, MouseButtonEventArgs e) =>
{
    Vector parent = (Vector)e.GetPosition(parentObj);
    Vector child = (Vector)e.GetPosition(childObj); // sender
    Point childPosition = (Point)(parent - child);
};
Shanahan answered 16/9, 2021 at 20:5 Comment(0)
F
-1

Hm. You have to specify window you clicked in Mouse.GetPosition(IInputElement relativeTo) Following code works well for me

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

I suspect that you need to refer to the window not from it own class but from other point of the application. In this case Application.Current.MainWindow will help you.

Formic answered 22/12, 2008 at 18:59 Comment(1)
Even though it's not what the author asked for, it got me on the right track, thanksImprovisatory

© 2022 - 2024 — McMap. All rights reserved.