所有决议WPF(独立分辨率)上相同的直径

时间:2017-09-28 14:43:31

标签: wpf pixels resolution-independence wpf-graphics

我有一个圆形的物体,直径为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的res显示器,但是当我开始降低时,自然一切都看起来更大。无论用户的显示器是什么分辨率,我都需要<Ellipse>标签的直径始终为3英寸。

谢谢!

1 个答案:

答案 0 :(得分:1)

我有好消息和坏消息。

好消息是WPF本身支持英寸作为大小单位。您只需将Width的{​​{1}}和Height设置为Ellipse即可获得WPF的最佳近似值。

坏消息是WPF根据Windows报告的DPI设置将英寸转换为物理像素,这通常与现实几乎没有相似之处。例如,Windows一直认为我旧ThinkPad中的显示器的间距为96dpi,但实际上接近120dpi。特别是移动屏幕具有过高或低于其像素密度的倾向。

有一个few unmanaged APIs可用来声明返回显示器的物理尺寸,虽然这些可能更可靠,但我怀疑结果仍然是命中或未命中。最有希望的似乎是使用SetupAPI在注册表中找到显示器的EDID块。可能值得一试。如果看起来足够可靠,您将能够通过将水平和垂直像素数除以报告的物理尺寸来手动计算有效DPI,执行任何必要的度量 - 英制转换(3in)。