样式仅适用于外部Grid.Resources时的第一次出现?

时间:2015-12-29 18:14:07

标签: xaml microsoft-metro winrt-xaml uwp

我有一个带有数据模板的gridview,其中包含一个togglebutton。 Gridview中项目的datatemplate中有一个网格,带有一个风格化的togglebutton。 togglebutton的样式位于Grid.Resources中。它运行正常,但是当我将样式从Grid.Resources移动到Page.Resources或App.xaml时,样式中定义的按钮内的内容将从除gridview中第一次出现的按钮之外的所有内容中消失。这是风格:

<Style TargetType="ToggleButton" x:Key="teststyle">
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Content">
            <Setter.Value>
                <Path HorizontalAlignment="Center" Stroke="Black" StrokeThickness="1.25"  VerticalAlignment="Center" Height="9" Width="9"  Stretch="Uniform" Fill="Black" Data="M 0,0 -11.78,-11.779 0,-23.561 l 1.061,1.061 -9.97,9.971 21.064,0 0,1.5 -21.064,0 9.97,9.968 L 0,0 Z" RenderTransformOrigin="0.5,0.5" >
                    <Path.RenderTransform>
                        <CompositeTransform Rotation="-90"/>
                    </Path.RenderTransform>
                </Path>
            </Setter.Value>
        </Setter>
</Style>

以下是行为的屏幕截图:http://imgur.com/a/8iZaD当样式位于Grid.Resources中时,顶部图像是原始图像,底部是样式移动时的底部图像。

3 个答案:

答案 0 :(得分:1)

您可以使用样式中的ContentTemplate而不是内容来解决此问题。

<Page.Resources>
    <Style TargetType="ToggleButton">
        <Setter Property="Padding" Value="0"/>
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Path HorizontalAlignment="Center" Stroke="Black" StrokeThickness="1.25"  VerticalAlignment="Center" Height="9" Width="9"  Stretch="Uniform" Fill="Black" Data="M 0,0 -11.78,-11.779 0,-23.561 l 1.061,1.061 -9.97,9.971 21.064,0 0,1.5 -21.064,0 9.97,9.968 L 0,0 Z" RenderTransformOrigin="0.5,0.5" >
                        <Path.RenderTransform>
                            <CompositeTransform Rotation="-90"/>
                        </Path.RenderTransform>
                    </Path>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

答案 1 :(得分:1)

Style可以在DataTemplate之外使用,此处的问题是Path您设置为Content的{​​{1}}。

ToggleButton中的XAML资源必须是可共享的(请参阅XAML resources must be shareable):

  

对于Style中存在的对象,该对象必须为 可共享

     

需要可共享是因为,当在运行时构造和使用应用程序的对象树时,对象不能存在于树中的多个位置。在内部,资源系统会在请求每个XAML资源时创建要在应用程序的对象图中使用的资源值的副本。

ResourceDictionary永远无法共享且UIElement继承自Path,因此UIElement无法共享。在Path中设置Style并将DataTemplate放在Style之外时,项目中的每个DataTemplate都会应用ToggleButton,但是Style只能显示一次,因为它不可共享。要对其进行测试,您可以在Path中添加一个对象,如:

Style

然后你会发现<Style x:Key="teststyle" TargetType="ToggleButton"> <Setter Property="Padding" Value="0" /> <Setter Property="Content"> <Setter.Value> <Path Width="9" Height="9" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0,0 -11.78,-11.779 0,-23.561 l 1.061,1.061 -9.97,9.971 21.064,0 0,1.5 -21.064,0 9.97,9.968 L 0,0 Z" Fill="Black" RenderTransformOrigin="0.5,0.5" Stretch="Uniform" Stroke="Black" StrokeThickness="1.25"> <Path.RenderTransform> <CompositeTransform Rotation="-90" /> </Path.RenderTransform> </Path> </Setter.Value> </Setter> <Setter Property="Background" Value="Red" /> </Style> 的所有背景都变成了红色。您也可以直接在ToggleButton中添加两个ToggleButton,如:

StackPanel

您还可以找到只有第一个<StackPanel> <ToggleButton Style="{StaticResource teststyle}" /> <ToggleButton Style="{StaticResource teststyle}" /> </StackPanel> 的路径。

当你将ToggleButton放在Style内时,每个项目都有自己的DataTemplate,所以它运行正常。

如果你像{Jean-SébastienDupuy所说的那样使用Resources,那么ContentTemplate就会变成Value,因为它来自DataTemplate,所以它是可分享的,所以它也有效细

答案 2 :(得分:0)

在XAML中移动样式的最佳方法是使用Blend设计器。

您可以在Blend的参考资料部分查看和整理您的样式。之后,您可以将本地样式拖放到App.xaml或Resources.xaml中。所有参考文献都会自动更新,您可以从下面的gif图片中查看。

enter image description here