我“有点”用以下策略解决了这个问题:
- 我的 MainWindow 有一个 ViweBox 作为 LayoutRoot,它的 Child 是一些代表物理对象的容器控件(在本例中为边框);
- ViewBox 和其中的所有内容都被定义为 WPF 单位是毫米。因此,如果产品的物理宽度为 68mm,则容器控件的 Width 属性为 78。嵌套在其中的所有其他内容都被视为 WPF 单位是实际的毫米;
- ViewBox 的 Width 和 Height 使用乘以 (96/25.4) 的 ValueConverter 绑定到容器控件的 Height 和 Width;
- 由于视图框内的所有内容都被缩放以适应(ViewBox.Stretch=Uniform),因此值转换器只是调整了视图框的大小,其余的布局调整由 ViewBox 嵌入式渲染转换实现(我认为它足够高效)。
我的 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">
(...)
我的代码隐藏:
(...)
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (double)value * (96/25.4);
}
(...)
当然是“我怎么能确定 DPI 实际上是 96?” 没有解决,但可以封装,最终结果与预期的结果足够接近,就我的目的而言。