How to position windows correctly at 120 DPI in WPF

If you want to place a window at a specific place in WPF, it will work pretty much as you expect—unless your DPI is 120 (the default is 96). Here’s a sample that shows how to put it where you want.

In this case, I want to put a window just under another control, aligned to its left side.

 

CalcWindow calc = new CalcWindow();
Point point = this.PointToScreen(
    new Point(0, this.ActualHeight));
 
PresentationSource source = 
    PresentationSource.FromVisual(control);
 
double dpiX = 
    96.0 * source.CompositionTarget.TransformToDevice.M11;
double dpiY = 
    96.0 * source.CompositionTarget.TransformToDevice.M22;
 
calc.Left = point.X * 96.0 / dpiX;
calc.Top = point.Y * 96.0 / dpiY;
 
calc.Show();

The crux of this is getting the current DPI. You could use P/Invoke to call native methods to get this, but the transformation matrix contains the same information as well.

2 thoughts on “How to position windows correctly at 120 DPI in WPF

  1. SpeziFish

    Great, exactly what I need. Thanks.
    But in my case it works even with out the dpi parameter:


    double dpiX = source.CompositionTarget.TransformToDevice.M11;
    double dpiY = source.CompositionTarget.TransformToDevice.M22;
    calc.Left = point.X / dpiX;
    calc.Top = point.Y / dpiY;

  2. Ivo Milanov

    Actually the PointToScreen converts a point measured in DIPs to a point measured in screen cordinates – e.g. PIXELS.

    This means that the DPI setting must be taken into account if screen resolution is different than 96 in the case of which one DIP == one PIXEL.

Comments are closed.