Getting the Absolute Position
       by kirupa  |  30 December 2009

Imagine a world where you didn't have to deal with crazy positioning schemes. In this world, everything makes sense. Up is truly up, right is truly right, and the top-left corner always has a 0 for its x/y coordinates. Of course, while you may think such a world does not exist, you get very close in Silverlight and WPF if all you want to do is read an element's position.

In this short article, I will explain just that - how to read the position of an element with the added advantage that your reading is independent of whatever layout container the element is in. This is possible thanks to the TransformToVisual method, and the following two lines of code give an example of its use:

GeneralTransform generalTransform = myElement.TransformToVisual(null);
Point point = generalTransform.Transform(new Point());

Before looking at the code, let's set up an example first. My application consists of a UI that looks as follows:

ss1

[ a simple UI with a handful of elements ]

Right now, I am interested in the position of the green Log-In button. The way I would get the position is by taking the above two lines of code and replacing the highlighted word with the actual name of the green button itself:

GeneralTransform generalTransform = logInButton.TransformToVisual(null);
Point point = generalTransform.Transform(new Point());

In our code, the position is calculated by simply taking the the distance from the top-left corner of your application. That is what the TransformToVisual method returns when a null argument is passed in. The position is originally stored as a GeneralTransform object with a lot of additional things that we don't care about, so in the second line, we distill the information that we want and store it in our Point object called point.

To get the actual X and Y positions from the point object, simply call the X and Y properties on it:

MessageBox.Show(point.X + " " + point.Y);

This wraps up what you most likely came here to learn about - how to get the absolute position of an element with your application's top-left corner as the origin.

Use LayoutUpdated Instead of Loaded
The last thing I will briefly discuss is one quirk in Silverlight that you may not have in WPF. It is very common for you to have any code related to layout and position be called from a Loaded event's event handler.

Unfortunately, Loaded does not mean the same as "everything has been laid out as planned." That means, if you place your TransformToVisual code inside the Loaded event handler, the values returned may not exactly be accurate. Instead, if you want to get the absolute position the moment your application "loads", use the LayoutUpdated event instead. That event only fires after everything has been laid out, so the position returned will be accurate.

Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!

Kirupa's signature!




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.