Windows应用商店应用布局差异

时间:2013-03-14 20:56:52

标签: xaml canvas microsoft-metro windows-runtime windows-store-apps

我正在使用Viewbox来缩放固定大小的画布(包含各种路径,这些路径一起形成一个有意义的画面)。

<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" />
        </Style>
    </StackPanel.Resources>
    <Viewbox>
        <Canvas Width="5" Height="5">
            <Path Data="M 1,1 h 3 v 3 h -3 z" />
        </Canvas>
    </Viewbox>
    <Viewbox>
        <Canvas Width="6" Height="6">
            <Path Data="M 1,1 h 4 v 4 h -4 z" />
        </Canvas>
    </Viewbox>
</StackPanel>

当我在PC上本地渲染时,此xaml显示在顶部,如在模拟器上渲染时显示在底部。当模拟器产生所需的结果时,有人可以向我解释为什么第二条路径超出了红色面板吗?

rendered natively on my PC rendered on an emulator

2 个答案:

答案 0 :(得分:5)

确实没有差异......发生的事情是你正在拍摄的东西非常小(你的路径非常小):

screenshot

看看小盒子

...并将其缩放得非常大,并通过UseLayoutRounding告诉布局舍入到最近的整个像素

结果不可靠的原因是Path s与Canvas无关,因为它实际上没有布局其内容。因此,当你的一个路径点落在不均匀的像素边界上(这可能发生在某些屏幕分辨率而不是其他屏幕分辨率上)时,它会四舍五入到未缩放画布内的最近的虚拟像素,并且会从{{1}缩放然后再次舍入到最近的整个像素(使用由Viewbox缩放确定的Viewbox相同的比例)加剧舍入误差。如果我们关闭Canvas(默认为透明)将StackPanel.Background设置为绿色并按下笔触颜色的不透明度,则可以更轻松地看到此图示:

screenshot

您可以看到路径舍入与画布不同

因此,您必须关闭Canvas.Background,以便在操作中携带小数点或简化布局,以便不会发生错误。

例如,如果您通过删除不适当且多余的固定大小画布并设置UseLayoutRounding来让路径自行缩放,则最终得到:

Path.Stretch = Uniform

导致: screenshot

可能就是你真正想要的

然而,如果这是一个过度简化,并且你实际上有多个路径要打算放在 <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> 中,我建议你使用一个实际上有自己布局的容器,显而易见的选择是{{1这样你仍然可以让路径与Canvas一起缩放,使它们处于锁定状态(Grid s不会布置它们的子节点)。代码看起来像:

Grid

,结果与没有辅助容器的结果相同

希望这有助于确认

答案 1 :(得分:1)

我可以使用模拟器在我的机器上重现问题,显示分辨率为2560x1440,画布如下所示。

<Canvas Width="4" Height="4">
    <Rectangle Width="4" Height="4" Fill="Blue" ></Rectangle>
</Canvas>

对于上面的片段 - 画布溢出/超出红色面板。

<Canvas Width="6" Height="6">
    <Rectangle Width="6" Height="6" Fill="Blue" ></Rectangle>
</Canvas>

对于上面的片段 - 画布下溢/不适合红色面板,并在红色面板的右边缘留下一些空间。

如果画布大小保持为5的倍数,则它适合红色面板。

它似乎不是Path的一个问题,因为它也用rect再现。它似乎是ViewBox扩展的问题。我发现在stackpanel上使用UseLayoutRounding="False" - 问题无法重现。在查看ViewBox扩展问题时,我还发现了related thread。它建议使用SnapsToDevicePixels属性,但不适用于Windows应用商店xaml应用。

总之,虽然我不是具有viewbox扩展算法内部知识的专家,但它似乎是ViewBox扩展的一个问题。可能的解决方法是将UseLayoutRounding设置为false,如果它在另一台计算机上通过测试。 5的倍数看起来不像是一个好的解决方法,但你可以检查。另外一个注意事项 - 如果你只是想知道它为什么会发生这种情况,那么你就会得到答案,并且可能会出现一些像素的下溢/溢出对你的应用程序而言可能很重要。