实际上并没有差异...发生的事情是你正在处理一个非常小的东西(你的路径非常小):
![screenshot](https://istack.dev59.com/2rdpS.webp)
。然后将其放大到极大并告诉布局使用
UseLayoutRounding
来四舍五入到最近的整个像素。
结果不可靠的原因是,
Path
是独立于
Canvas
缩放的,因为它实际上并没有布局其内容。因此,当您的某个路径点落在不均匀的像素边界上时(这可能会发生在某些屏幕分辨率上而在其他分辨率上则不会),它会四舍五入到未缩放画布内的最近虚拟像素,并且这是从
Viewbox
进行缩放,然后再次四舍五入到最近的整个像素(使用与
Canvas
缩放相同的比例)。这加剧了四舍五入误差。如果我们关闭
StackPanel.Background
(默认为透明),将
Canvas.Background
设置为绿色,并降低描边颜色的不透明度,则可以更容易地看到此现象:
![screenshot](https://istack.dev59.com/dAyt2.webp)
。
因此,您要么必须关闭
UseLayoutRounding
,以便在操作中保留小数点,要么简化布局,以避免出现错误。例如,如果您通过删除不适当和多余的固定大小画布并设置
Path.Stretch = Uniform
来让路径自己缩放,则最终结果如下:
<StackPanel Background="Red" Width="400" UseLayoutRounding="True">
<StackPanel.Resources>
<Style TargetType="Viewbox">
<Setter Property="Height" Value="400" />
<Setter Property="Margin" Value="0,0,0,50" />
</Style>
<Style TargetType="Path">
<Setter Property="Stroke" Value="Blue" />
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="Stretch" Value="Uniform" />
</Style>
</StackPanel.Resources>
<Viewbox>
<Path Data="M 1,1 h 3 v 3 h -3 z" />
</Viewbox>
<Viewbox>
<Path Data="M 1,1 h 4 v 4 h -4 z" />
</Viewbox>
</StackPanel>
导致:
![屏幕截图](https://istack.dev59.com/C6W4F.webp)
可能是您实际正在寻找的内容
但是,如果这只是一种过度简化,而您实际上有多条路径要放在您的Canvas
中,我建议您使用一个可以自行布局的容器,最明显的选择是Grid
,这样您仍然可以使路径与Grid
一起自动缩放,让它们保持同步(Canvas
不会对其子项进行布局)。代码如下:
<StackPanel Background="Red" Width="400" UseLayoutRounding="True">
<StackPanel.Resources>
<Style TargetType="Viewbox">
<Setter Property="Height" Value="400" />
<Setter Property="Margin" Value="0,0,0,50" />
</Style>
<Style TargetType="Path">
<Setter Property="Stroke" Value="Blue" />
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="Stretch" Value="Uniform" />
</Style>
</StackPanel.Resources>
<Viewbox>
<Grid Width="5" Height="5">
<Path Data="M 1,1 h 3 v 3 h -3 z" />
</Grid>
</Viewbox>
<Viewbox>
<Grid Width="6" Height="6">
<Path Data="M 1,1 h 4 v 4 h -4 z" />
</Grid>
</Viewbox>
</StackPanel>
结果与没有辅助容器的结果相同
希望这能帮到你 -ck