wpf에서 창 내 요소의 절대 위치 가져 오기


88

두 번 클릭 할 때 창 / 루트 요소와 관련된 요소의 절대 위치를 얻고 싶습니다. 부모 내의 요소의 상대적 위치는 내가 도달 할 수있는 모든 것이며 내가 도달하려는 것은 창에 대한 상대적인 지점입니다. 나는 화면에서 요소의 포인트를 얻는 방법에 대한 솔루션을 보았지만 창에는 없습니다.

답변:


128

BrandonS가 원하는 것은 루트 요소와 관련된 마우스 의 위치가 아니라 일부 하위 요소의 위치입니다.

이를 위해 TransformToAncestor 메서드가 있습니다.

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

myVisual방금 두 번 클릭 한 요소는 어디에 있으며 rootVisualApplication.Current.MainWindow 또는 원하는 위치를 기준으로합니다.


2
안녕하세요 저는 이것을 시도하고 다음 예외가 발생합니다. System.InvalidOperationException이 처리되지 않았습니다. Message = 지정된 Visual이이 Visual의 조상이 아닙니다. Source = PresentationCore 아이디어가 있습니까?
RoflcoptrException

8
Visual.TransformToAncestor는 포함 된 Visual을 전달하는 경우에만 작동합니다. 두 요소의 상대 위치를 원하고 하나에 다른 요소가 포함되지 않은 경우 Visual.TransformToVisual을 대신 사용할 수 있습니다.
Robert Macnee

5
TransformToVisual에는 컨트롤이 팝업에있는 경우 문제가 될 수있는 공통 조상이 여전히 필요합니다
Adam Mills

1
매우 직관적입니다! "GetRelativePosition"호출에 이것을 래핑 할 수 없습니까? :-) 도와 주셔서 감사합니다. +1
Paul

1
@ cod3monk3y-또는 아마도 Microsoft 오픈 소스 WPF의 경우 풀 요청을 보낼 것입니다. :-)
Paul

43

창 내에서 UI 요소의 절대 위치를 얻으려면 다음을 사용할 수 있습니다.

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

사용자 컨트롤 내에 있고 해당 컨트롤 내에서 UI 요소의 상대적 위치를 원하는 경우 다음을 사용하면됩니다.

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 화면에서) 예상대로 작동하지 않을 수 있습니다.
Drew Noakes

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 2015

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도움이 될 것입니다.


그것은 저자가 무엇을 요구하지 비록, 그것은 곧 정상 궤도에 감사 저를 얻었다
라디 Ondris
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.