Is it possible to display a WPF Control in real-world, device-independent units? Milimeters, for example?

北慕城南 提交于 2021-01-28 06:34:29

问题


I am designing a product emulator in WPF. Our company sells a handheld electronic medical device, and we'd like to experiment with user interaction with a "virtual", skinned (sort of) GUI to represent buttons and leds.

Is there a way to "force" WPF to display stuff with its real-world dimension on the screen (by getting monitor dpi information, or something like this)?

As another example, suppose I can layout a plastic, standard-sized Credit Card using WPF controls (DockPanels, Labels, Canvases, etc.), could I consistently display it with the dimensions of a real credit card, across different desktops/laptops?

UPDATE:

I've found a clever way to design in "real milimeters" by using a ViewBox as the LayoutRoot of my window. Size of anything inside can be "designed in milimeters", and will be displayed in physical size PROVIDED that I can get the right pixel size for the ViewBox. And THAT remain a certain mistery:

  • The relation between pixels and milimeters in my desktop seems to be 3.5 (where does this number come from?
  • How could I implement a code-behind DataBound property or ValueConverter so that I could define a Zoom Level (via slider or hardcoded) to display a scaled (larger) version of the device if needed?

回答1:


I "sort of" solved the problem with the following strategy:

  • My MainWindow has a ViweBox as LayoutRoot, and its Child is some container control (Border in this case) which represent the physical object;
  • The ViewBox and everything inside it is defined as if WPF units were milimeters. So, if the product has a physical Width of 68mm, the Width property of the container control is 78. Everything else that is nested inside is treated as if WPF units were actual milimeters;
  • The ViewBox has its Width and Height bounded to the Height and Width of the container control using a ValueConverter which multiplies by (96/25.4);
  • Since everything inside a viewbox is scaled to fit (ViewBox.Stretch=Uniform), the value converter just resizes the viewbox, and the rest of layout redimensioning is achieved by the ViewBox embedded rendering transform (that I assume to be efficient enough).

My XAML:

<Window.Resources>
    <local:PixelsToMilimeters x:Key="SizeConverter"/>       
</Window.Resources>

<Viewbox x:Name="LayoutRoot" Stretch="Uniform"
    Width="{Binding Width, ElementName=Case, Converter={StaticResource SizeConverter}}"
    Height="{Binding Height, ElementName=Case, Converter={StaticResource SizeConverter}}">
    <Border x:Name="Case" Width="108" Height="68">
    (...)

My code-behind:

    (...)
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (double)value * (96/25.4);
    }
    (...)

Of course the "how can I be sure that DPI is actually 96?" is not solved, but that could be encapsulated, and the final result is close enough to the expected one, for my purposes.



来源:https://stackoverflow.com/questions/16111800/is-it-possible-to-display-a-wpf-control-in-real-world-device-independent-units

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!