在 wpf 中获取窗口中元素的绝对位置

当双击某个元素时,我希望得到它相对于 window/root 元素的绝对位置。元素在其父元素中的相对位置是我所能得到的,我想要得到的是相对于窗口的点。我已经看到了如何在屏幕上得到一个元素的点,而不是在窗口的解决方案。

134431 次浏览

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.

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.

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 an 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;

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.

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.

childObj.MouseDown += (object sender, MouseButtonEventArgs e) =>
{
Vector parent = (Vector)e.GetPosition(parentObj);
Vector child = (Vector)e.GetPosition(childObj); // sender
Point childPosition = (Point)(parent - child);
};