Wpf'de pencere içindeki elemanın Mutlak Konumunu alın


89

Çift tıklandığında pencere / kök eleman ile ilişkili olarak bir elemanın mutlak konumunu almak istiyorum. Öğenin üst öğesi içindeki göreceli konumu, ulaşabildiğim tek şey ve ulaşmaya çalıştığım şey, pencereye göre nokta. Ekranda bir öğenin noktasının nasıl alınacağına dair çözümler gördüm ama pencerede değil.

Yanıtlar:


130

Bence BrandonS'ın istediği farenin kök öğeye göre konumu değil, bazı alt öğelerin konumu.

Bunun için TransformToAncestor yöntemi vardır:

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

myVisualYalnızca çift tıklanan öğe nerede ve rootVisualApplication.Current.MainWindow veya göreceli konumu istediğiniz şey.


3
Merhaba bunu denedim ve aşağıdaki istisnayı alıyorum: System.InvalidOperationException işlenmedi. Message = Belirtilen Visual, bu Görselin atası değil. Kaynak = PresentationCore Herhangi bir fikriniz var mı?
RoflcoptrException

8
Visual.TransformToAncestor yalnızca içeren bir Visual. İki öğenin göreli konumunu istiyorsanız ve biri diğerini içermiyorsa, bunun yerine Visual.TransformToVisual'ı kullanabilirsiniz.
Robert Macnee

5
TransformToVisual, kontrol bir açılır pencerede ise sorunlu olabilecek ortak bir ataya ihtiyaç duymaya devam ediyor
Adam Mills

1
Süper sezgisel! Bunu bir "GetRelativePosition" çağrısına saramazlar mı? :-) Yardım için teşekkürler. +1
Paul

1
@ cod3monk3y - veya belki, Microsoft WPF kaynaklarını açarsa onlara bir çekme isteği gönderirim :-)
Paul

43

Pencerede bir UI öğesinin mutlak konumunu elde etmek için şunları kullanabilirsiniz:

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

Bir Kullanıcı Kontrolü içindeyseniz ve bu kontrol içindeki UI öğesinin göreceli konumunu istiyorsanız, şunları kullanmanız yeterlidir:

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

position.X -= controlPosition.X;
position.Y -= controlPosition.Y;

4
Ekran ölçeklemeniz% 100'e ayarlanmadıysa (yani yüksek DPI ekranlarda), bunun muhtemelen beklediğiniz şeyi yapmayacağını unutmayın.
Drew Noakes

18

Bu yöntemi statik bir sınıfa ekleyin:

 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 relativeToScreeniçin paramater trueüstten yerleştirme için tüm ekranın veya sol köşesine falseuygulama penceresinin sol üst köşesinden yerleştirme için.


1
Bu harika çalışıyor! Bunu RenderTransform, öğeyi değiştirerek bir görüntüyü ekran üzerinde veya dışında kaydıran bir animasyonla kullanıyorum ve bu nedenle öğenin ekrandaki mutlak konumunu bilmesi gerekiyor.
cod3monk3y

6

.NET 3.0'dan beri *yourElement*.TranslatePoint(new Point(0, 0), *theContainerOfYourChoice*).

Bu size düğmenizin 0, 0 noktasını ancak konteynere doğru verecektir. (0, 0 gibi başka bir nokta da verebilirsiniz)

Doküman için burayı kontrol edin.


0

Hm. Mouse.GetPosition(IInputElement relativeTo) Aşağıdaki kodda tıkladığınız pencereyi belirtmeniz gerekiyor benim için iyi çalışıyor

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

Pencereye kendi sınıfından değil, uygulamanın başka bir noktasından bakmanız gerektiğinden şüpheleniyorum. Bu durumda Application.Current.MainWindowsize yardımcı olacaktır.


Yazarın istediği bu olmasa da, beni doğru yolda
tuttu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.