Handmatig plaatsen van een WPF window

Bij het positioneren van visuals, gebruikt WPF ‘device independent pixels’ (DIP). Een DIP is altijd 1/96 inch groot.

WPF zorgt zelf voor opschaling wanneer de schermresolutie anders is dan 96 pixels per inch (dpi). Bijvoorbeeld in het geval van een laptop die een 120 dpi scherm heeft.

Bij het handmatig positioneren van een WPF window, maak je gebruik van de Left en Top properties. En ook dit zijn DIP properties.

Een tijdje terug wilde ik een WPF window positioneren op de plek van een button. Een gebruiker klikt op een button en het window verschijnt precies op die plek, zodat er geen grote muisbewegingen nodig zijn.

Ik loste dat als volgt op:

Point screenPos = button.PointToScreen(new Point(0,0));
dialog.Left = screenPos.X;
dialog.Top = screenPos.Y;

En dat werkte….. op mijn 96 dpi scherm. Helaas kwam ik al snel tot de ontdekking dat het op mijn laptop met 120 dpi scherm niet werkte.

Wat blijk nu? PointToScreen retourneert geen DIP coördinaat, maar een *echt* schermcoördinaat. Tsja… als ik de naamgeving van deze methode wat serieuzer had genomen, had ik het kunnen vermoeden.

Gelukkig is het mogelijk om een schermcoördinaat te transformeren naar een DIP coördinaat. Dat gaat via de PresentationSource klasse. De volgende helper method maakt het nu mogelijk om een DIP  coördinaat van een willekeurige WPF visual op te vragen:

public static Point DeviceIndependentPosition(Visual element)
{
    Point screenPos = element.PointToScreen(new Point(0, 0));
    PresentationSource src = PresentationSource.FromVisual(element);
    return src.CompositionTarget.TransformFromDevice.Transform(screenPos);
}

Eventueel kan hier een extension method (voor Visual) van gemaakt worden. Het plaatsen van een WPF window op de positie van een button is nu eenvoudig:

Point buttonDip = DeviceIndependentPosition(button);
dialog.Left = buttonDip.X;
dialog.Top = buttonDip.Y;
Advertenties
Dit bericht werd geplaatst in .NET, C#, WPF. Bookmark de permalink .

Geef een reactie

Vul je gegevens in of klik op een icoon om in te loggen.

WordPress.com logo

Je reageert onder je WordPress.com account. Log uit / Bijwerken )

Twitter-afbeelding

Je reageert onder je Twitter account. Log uit / Bijwerken )

Facebook foto

Je reageert onder je Facebook account. Log uit / Bijwerken )

Google+ photo

Je reageert onder je Google+ account. Log uit / Bijwerken )

Verbinden met %s