0

I have a physical object in the shape of a circle that measures 3 inches in diameter. My application transposes this circle shape onto the screen so the user can visually check off what they see into the application from the circle object. The problem I have is that I need the circle object to be 3 inches in diameter and appear the same size on all monitor types and all resolutions.

Is this possible? I am using WPF and have something like this already:

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

My inches to DIU converter looks something like this:

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

As expected, this works very well on a say a 1920 x 1200 res monitor, but when I start to get lower, naturally everything looks bigger. I need the diameter of my <Ellipse> tag to always be 3 inches no matter what resolution the person's monitor is.

Thanks!

4

1 回答 1

1

I have good news and bad news for you.

The good news is that WPF natively supports inches as a size unit. You can simply set the Width and Height of your Ellipse to 3in, and you will get WPF's best approximation.

The bad news is that WPF translates inches to physical pixels according to the DPI settings reported by Windows, which often bear little semblance to reality. For example, Windows has long believed the display in my old ThinkPad has a pitch of 96dpi, but it is actually closer to 120dpi. Mobile screens in particular have a tendency to over- or under-report their pixel density.

There are a few unmanaged APIs available that purport to return the physical dimensions of a display, and while these might be more reliable, I suspect the results will still be hit-or-miss. The most promising seems to be using SetupAPI to locate the display’s EDID block in the registry. Might be worth a shot. If it seems reliable enough, you’ll be able to manually compute the effective DPI by dividing the horizontal and vertical pixel counts by the reported physical dimensions, performing any necessary metric-to-imperial conversions (1 in = 2.54 cm).

于 2017-09-28T15:19:29.077 回答