This may sound like a duplicate question, but I promise it is not. I have already looked at the answers provided in other questions, such as the one at the following link:
The problem is, they are not returning the correct DPI.
I know for a fact that my monitor (Dell U3415W) has a DPI of 109 ppi. The resolution is 3440x1440.
In WPF, I have attempted the following methods to get the DPI of my screen:
//Method 1
var dpi_scale = VisualTreeHelper.GetDpi(this);
double dpiX = dpi_scale.PixelsPerInchX;
double dpiY = dpi_scale.PixelsPerInchY;
//Method 2
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
{
double dpiX = g.DpiX;
double dpiY = g.DpiY;
}
//Method 3
PresentationSource source = PresentationSource.FromVisual(this);
double dpiX, dpiY;
if (source != null)
{
dpiX = 96.0 * source.CompositionTarget.TransformToDevice.M11;
dpiY = 96.0 * source.CompositionTarget.TransformToDevice.M22;
}
All three of the above methods return 192 as my DPI (The scale factor being returned in methods #1 and #3 is 2).
I am writing code in which I need to reliably display the distances (in physical units such as centimeters) between some objects on the screen, and this code will not just be running on my screen so I can't just hardcode "109" into it.
On a related note, I am mystified by what seems to be an instance of WPF using actual pixels instead of device-independent pixels.
I have the following XAML declaring a window with a simple grid and a rectangle inside of the grid:
<Window x:Class="MyTestWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Height="768"
Width="1024">
<Grid x:Name="MainObjectLocationGrid">
<Rectangle x:Name="MainObjectLocationRectangle" HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</Window>
In the code-behind, I have some code that sets some properties on that rectangle:
MainObjectLocationRectangle.Width = 189.5625;
MainObjectLocationRectangle.Height = 146.4;
MainObjectLocationRectangle.Fill = new SolidColorBrush(Colors.White);
MainObjectLocationRectangle.Stroke = new SolidColorBrush(Colors.Transparent);
MainObjectLocationRectangle.StrokeThickness = 0;
MainObjectLocationRectangle.Margin = new Thickness(0, 0, 0, 0);
When my rectangle appears on the screen, the rectangle is 4.4cm x 3.4cm in size. WPF says that 1 device-independent pixel is 1/96th of an inch, so I would assume that 96 dip is 1 inch (which is 2.54 cm). Therefore 189.5625 dip should be 1.9746 inches (or 5.01 cm). Yet it seems that it isn't using dip in this instance. If we insert my monitor's actual resolution (109 dpi) into the equation, we get the actual size of the rectangle being displayed:
189.5625 pixels / 109 dpi = 1.7391 inches (or 4.4 cm)
Yet in the WPF documentation it states that the Width and Height properties use device-independent pixels:
So, to conclude:
(1) Why are all the accepted methods for querying the DPI not returning the correct DPI to me?
(2) Why does it seem like when I set the size of the rectangle, it is interpreting that size in units of pixels rather than device-independent pixels?
Thanks for any help!!!