wpfでウィンドウ内の要素の絶対位置を取得します


88

ダブルクリックしたときのウィンドウ/ルート要素に対する要素の絶対位置を取得したいと思います。親内の要素の相対位置は、私が到達できるように見えるすべてであり、私が到達しようとしているのは、ウィンドウに対する相対的なポイントです。画面上ではなく、ウィンドウ上で要素のポイントを取得する方法の解決策を見てきました。

回答:


127

BrandonSが望んでいるのは、ルート要素に対するマウスの位置ではなく、子孫要素の位置だと思います。

そのために、TransformToAncestorメソッドがあります。

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

myVisualダブルクリックしたばかりの要素はどこにあり、rootVisualApplication.Current.MainWindowまたは任意の相対位置になります。


2
こんにちは私はこれを試しましたが、次の例外が発生します:System.InvalidOperationExceptionが処理されませんでしたMessage =指定されたビジュアルはこのビジュアルの祖先ではありません。Source = PresentationCore何かアイデアはありますか?
roflcoptrException 2010年

8
Visual.TransformToAncestorは、含まれているVisualを渡した場合にのみ機能します。2つの要素の相対位置が必要で、一方にもう一方が含まれていない場合は、代わりにVisual.TransformToVisualを使用できます。
Robert Macnee 2010年

5
TransformToVisualには、コントロールがポップアップにある場合に問題となる可能性のある共通の祖先が必要です
Adam Mills

1
超直感的!これを「GetRelativePosition」呼び出しでラップすることはできませんか?:-) 助けてくれてありがとう。+1
ポール

1
@ cod3monk3y-または、MicrosoftがWPFをオープンソースにしている場合は、プルリクエストを送信します:-)
Paul

41

ウィンドウ内の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画面の場合)、これはおそらく期待どおりに機能しないことに注意してください。
ドリューノアケス2016

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


0

うーん。Mouse.GetPosition(IInputElement relativeTo) 次のコードでクリックしたウィンドウを指定する必要があります

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

独自のクラスからではなく、アプリケーションの他のポイントからウィンドウを参照する必要があると思います。この場合Application.Current.MainWindowはあなたを助けます。


それは著者が求めたものではありませんが、それは私を正しい軌道に乗せました、ありがとう
LadislavOndris19年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.