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

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

7 ответов

Решение

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

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

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

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

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

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;

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

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

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

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

Проверьте здесь для док.

Я создал класс TextBlockEx, производный от TextBox, и установил его в конструкторе только для чтения, обтекание текстом true, что сделало его похожим на TextBlock.

      public class TextBlockEx : TextBox
{
    public TextBlockEx()
    {
        base.BorderThickness = new Thickness(0);
        IsReadOnly = true;
        TextWrapping = TextWrapping.Wrap;
        //Background = Brushes.Transparent; // Uncomment to get parent's background color
    }
}
      childObj.MouseDown += (object sender, MouseButtonEventArgs e) =>
{
    Vector parent = (Vector)e.GetPosition(parentObj);
    Vector child = (Vector)e.GetPosition(childObj); // sender
    Point childPosition = (Point)(parent - child);
};

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

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

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

Другие вопросы по тегам