【问题标题】:Style only works for the first occurence when outside Grid.Resources?样式仅适用于 Grid.Resources 之外的第一次出现?
【发布时间】:2016-04-03 15:59:15
【问题描述】:

我有一个带有数据模板的网格视图,其中包括一个切换按钮。 Gridview 中项目的数据模板中有一个网格,带有一个风格化的切换按钮。切换按钮的样式位于 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 中时的原始图像,下图是样式移动时的图像。

【问题讨论】:

  • 您是否将 ToggleButton Style 显式设置为此 StaticResource 键(在您的数据模板中)?
  • @igrali 这是我的 ToggleButton 声明在数据模板中的样子:&lt;ToggleButton HorizontalAlignment="Right" VerticalAlignment="Center" Style="{StaticResource teststyle}" IsChecked="{x:Bind Path=Liked, Converter={StaticResource downvoteconverter},Mode=OneWay}" IsThreeState="False" Command="{x:Bind downvotecommand}"/&gt;

标签: xaml microsoft-metro winrt-xaml uwp


【解决方案1】:

您可以通过在您的样式中使用 ContentTemplate 而不是 Content 来解决此问题。

<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>

【讨论】:

  • 这解决了这个问题。您知道为什么 Content 属性的行为不正确吗?
  • 老实说不 :) 我正在尝试调查根本原因,但还没有找到答案。
【解决方案2】:

Style 可以在你的DataTemplate 之外工作,这里的问题是你设置为ContentToggleButtonPath

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

对于存在于ResourceDictionary 中的对象,该对象必须是可共享

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

但是UIElement 永远不能共享,Path 继承自 UIElement,所以 Path 是不可共享的。当在DataTemplate 中设置Style 并将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 时,每个项目都会有自己的Resources,所以它工作正常。

如果你像@Jean-Sébastien Dupuy 所说的那样使用ContentTemplate,那么Value 就变成了DataTemplate,它是可共享的,因为它源自FrameworkTemplate,所以它也可以正常工作。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 试过这个。还是一样的问题:(
    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2018-09-01
    • 2014-02-08
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    相关资源
    最近更新 更多