Как я могу получить правильный DPI моего экрана в WPF? - PullRequest
0 голосов
/ 13 февраля 2019

Это может звучать как дубликат вопроса, но я обещаю, что это не так.Я уже посмотрел ответы, представленные в других вопросах, например, по следующей ссылке:

Как получить DPI в WPF?

Проблемато есть, они не возвращают правильный DPI.

Я точно знаю, что мой монитор (Dell U3415W) имеет DPI 109 точек на дюйм.Разрешение 3440x1440.

В WPF я пытался получить следующие значения DPI для моего экрана:

//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;
}

Все три из приведенных выше методов возвращают 192 как мой DPI (масштабный коэффициент, возвращаемый в методах # 1 и # 3, равен 2).

Я пишу код, в котором мне нужно надежно отображать расстояния (в физических единицах, таких как сантиметры) между некоторымиобъекты на экране, и этот код не будет просто запускаться на моем экране, поэтому я не могу просто жестко ввести в него код «109».

В соответствующей заметке я озадачен тем, что кажется экземпляромWPF с использованием реальных пикселей вместо независимых от устройства пикселей.

У меня есть следующий XAML, объявляющий окно с простой сеткой и прямоугольником внутри сетки:

<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>

В кодеПозади у меня есть некоторый код, который устанавливает некоторые свойства этого прямоугольника:

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);

Когда мой прямоугольник появляется на экране, прямоугольник имеет размер 4.4cm x 3.4cm .WPF говорит, что 1 независимый от устройства пиксель равен 1/96 дюйма, поэтому я предполагаю, что 96 dip - это 1 дюйм (что составляет 2,54 см).Поэтому наклон 189,5625 должен составлять 1,9746 дюйма (или 5,01 см).Тем не менее, похоже, что он не использует dip в этом случае.Если мы вставим фактическое разрешение моего монитора (109 точек на дюйм) в уравнение, мы получим фактический размер отображаемого прямоугольника:

189,5625 пикселей / 109 точек на дюйм = 1,7391 дюйма (или 4,4 см)

Тем не менее, в документации WPF говорится, что свойства Width и Height используют независимые от устройства пиксели:

https://docs.microsoft.com/en-us/dotnet/api/system.windows.frameworkelement.width?view=netframework-4.7.2#System_Windows_FrameworkElement_Width

Итак, чтобы сделать вывод:

(1) Почемувсе принятые методы для запроса DPI не возвращают мне правильный DPI?

(2) Почему, когда я устанавливаю размер прямоугольника, мне кажется, что этот размер скорее интерпретируется в единицах пикселейчем зависит от устройства пикселей?

Спасибо за любую помощь !!!

...