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