在所有分辨率上圈出相同的直径 WPF(分辨率独立性)

Circle Same Diameter on All Resolutions WPF (Resolution Independence)

我有一个直径为 3 英寸的圆形物体。我的应用程序将这个圆形转置到屏幕上,这样用户就可以直观地核对他们从圆形对象看到的应用程序内容。我遇到的问题是我需要圆形对象的直径为 3 英寸,并且在所有监视器类型和所有分辨率上显示相同的大小。

这可能吗?我正在使用 WPF 并且已经有了这样的东西:

<Window.Resources>
    <behaviors:InchesToIndependentUnitsConverter x:Key="InchesToDeviceIndependentUnits" />
</Window.Resources>
...
<Ellipse x:Name="MyCircle" Height="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth}" Width="{Binding CircleDiameter, Converter={StaticResource InchesToDeviceIndependentUnits}}" Margin="0,0,0,20" Fill="White"  BorderBrush="Black" BorderThickness="1" VerticalAlignment="Top" HorizontalAlignment="Center"></Ellipse>
...

我的英寸到 DIU 转换器看起来像这样:

public class InchesToIndependentUnitsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo cultureInfo)
    {
        int diameterDIU = 0;
        if ((double)value > 0)
        {
            using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
            {
                diameterDIU = (int)((g.DpiX / 96) * value);
            }
        }
        return diameterDIU;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo cultureInfo)
    {
        throw new NotImplementedException();
    }

正如预期的那样,这在 1920 x 1200 分辨率的显示器上效果很好,但是当我开始降低分辨率时,自然一切看起来都更大了。我需要我的 <Ellipse> 标签的直径始终为 3 英寸,无论此人的显示器分辨率如何。

谢谢!

我有好消息和坏消息要告诉你。

好消息是 WPF 本机支持将英寸作为尺寸单位。您可以简单地将 EllipseWidthHeight 设置为 3in,您将获得 WPF 的最佳近似值。

坏消息是 WPF 会根据 Windows 报告的 DPI 设置将英寸转换为物理像素,这通常与现实情况不太一样。例如,Windows 长期以来一直认为我的旧 ThinkPad 中的显示屏间距为 96dpi,但实际上更接近 120dpi。移动屏幕尤其倾向于高估或低估其像素密度。

有一个 few unmanaged APIs 可用,声称 return 显示器的物理尺寸,虽然这些 可能 更可靠,但我怀疑结果仍然是碰碰运气。最有前途的似乎是使用 SetupAPI 在注册表中定位显示器的 EDID 块。可能值得一试。如果它看起来足够可靠,您将能够通过将水平和垂直像素数除以报告的物理尺寸来手动计算有效 DPI,并执行任何必要的公制到英制转换 (1 in = 2.54 cm)。