XAML样式和模板在Win8.1和WinPhone 8.1之间产生不同的视觉效果

时间:2014-08-23 11:04:19

标签: xaml windows-8.1 windows-phone-8.1

我根据我在Windows 8.1应用程序上完成的工作构建了一个通用应用程序。在该应用程序中,我使用路径以尽可能高质量地显示各种图标。

我用一种风格来做这件事:

<Style x:Key="UnstyledGraphicsButtonStyle" TargetType="Button">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Path Width="{Binding Width, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                      Height="{Binding Width, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                      Stretch="Uniform"
                      Fill="{Binding Foreground, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                      Data="{Binding Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
            </DataTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid>
                    <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="0">
                        <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="Left" Margin="6,4" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" FontFamily="Global User Interface"/>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

然后在项目模板中使用它,但为了测试,这里有一些代表项目模板的示例XAML:

<Grid Margin="6" HorizontalAlignment="Left">
    <Border Background="#FF4068B2" Width="60" Height="60">
        <Button Content="M28.770002,34.487999 L52.512001,34.487999 C57.570004,34.487999 61.676003,38.592999 61.676003,43.655998 L61.676003,66.703003 L19.609001,66.703003 L19.609001,43.655998 C19.609001,38.592999 23.711002,34.487999 28.770002,34.487999 z M55.210999,20.660004 L71.980995,20.660004 C76.409996,20.660004 80,24.250004 80,28.679003 L80,48.601002 L63.987999,48.601002 L63.987999,41.539001 C63.987999,36.476002 59.394997,32.375 53.723,32.375 L49.343998,32.375 C52.898998,29.796003 55.223,25.617002 55.223,20.890003 C55.223,20.812002 55.210999,20.738003 55.210999,20.660004 z M8.0200005,20.660004 L26.851999,20.660004 C26.851999,20.734003 26.84,20.808002 26.84,20.882004 C26.84,25.597004 29.149,29.765001 32.687996,32.343006 L27.125,32.343006 C21.452999,32.343006 16.859001,36.449005 16.859001,41.507004 L16.859001,48.597004 L0,48.597004 L0,28.679003 C0,24.250004 3.5940018,20.660004 8.0200005,20.660004 z M41.031006,9.156002 C47.512005,9.156002 52.762005,14.406003 52.762005,20.882004 C52.762005,27.363005 47.512005,32.613003 41.031006,32.613003 C34.555,32.613003 29.305004,27.363005 29.305004,20.882004 C29.305004,14.406003 34.555,9.156002 41.031006,9.156002 z M61.922005,0 C66.781006,-1.6088339E-07 70.719002,3.9409997 70.719002,8.8000002 C70.719002,13.656001 66.781006,17.597 61.922005,17.597 C57.063004,17.597 53.125004,13.660001 53.125004,8.8000002 C53.125004,3.9409997 57.063004,-1.6088339E-07 61.922005,0 z M17.355999,0 C22.215002,-1.6088339E-07 26.156002,3.9409997 26.156002,8.8000002 C26.156002,13.656001 22.215002,17.597 17.355999,17.597 C12.496002,17.597 8.5590019,13.660001 8.5590019,8.8000002 C8.5590019,3.9409997 12.496002,-1.6088339E-07 17.355999,0 z" Style="{StaticResource UnstyledGraphicsButtonStyle}" Width="50" Height="41.689375" Foreground="white" Padding="0" Background="transparent" BorderBrush="{x:Null}" IsEnabled="False" />
    </Border>
</Grid>

在Windows 8.1中,这与按钮中心的路径完美呈现:

Windows 8.1 path icon

但是,在Windows Phone 8.1上,它呈现如下:

Windows Phone 8.1 path icon

应该注意,示例中的硬编码宽度和高度值通常不是硬编码的。它们是通过模板设置的。以上只是一个示例,说明两个平台之间的渲染方式有何不同。如何使用它的一个例子是:

<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="60" Height="60" Visibility="{Binding ImageIsAvailable, Converter={StaticResource HideIfTrue}}">
    <Button Content="{Binding ImageContent}" Style="{StaticResource UnstyledGraphicsButtonStyle}" Width="{Binding ImageWidth50}" Height="{Binding ImageHeight50}" Foreground="white" Padding="0" Background="Transparent" BorderBrush="{x:Null}" IsEnabled="False" />
</Border>

换句话说,我将边框设置为某个方形的宽度和高度,然后指定我想要按钮的宽度,即减少10个像素。绑定完成是因为各种路径具有不同的实际宽度和高度,因此代码会调整它们以使它们在50x50的正方形中看起来很好。

我发现的唯一解决方案是将以下内容添加到模板中Border语句的末尾:

Width="60" Height="60" HorizontalAlignment="Left"

所以它读取

<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="0" Width="60" Height="60" HorizontalAlignment="Left">

现在,问题在于宽度和高度然后是硬编码而不是由父对象设置。虽然上面的例子使用了一个60px的边框和一个50px的按钮,但是我的应用中有些地方使用了不同的尺寸,因此希望避免模板中的硬编码尺寸。

我是否在XAML中做错了解释为什么Windows Phone XAML会以这种方式运行?

解决这个问题最干净/最好的方法是什么?

感谢。

菲利普

1 个答案:

答案 0 :(得分:2)

尝试将路径数据放入嵌套在Viewbox中的路径,如下所示?

<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}"
                        Width="60"
                        Height="60"
                        Visibility="{Binding ImageIsAvailable, Converter={StaticResource HideIfTrue}}">
                    <Button Style="{StaticResource UnstyledGraphicsButtonStyle}"
                            Width="{Binding ImageWidth50}"
                            Height="{Binding ImageHeight50}"
                            Foreground="white"
                            Padding="0"
                            Background="Transparent"
                            BorderBrush="{x:Null}"
                            IsEnabled="False" >
                    <Button.ContentTemplate>
                        <DataTemplate>
                            <Viewbox>
                                <Path Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                                      Width="{Binding ImageWidth50}"
                                      Height="{Binding ImageHeight50}"
                                      StrokeThickness="2"
                                      Stretch="Uniform"
                                      Data="Path Data Here" />
                            </Viewbox>
                        </DataTemplate>
                    </Button.ContentTemplate>
                    </Button>
                </Border>