【问题标题】:Changing style from inside a DataTrigger从 DataTrigger 内部更改样式
【发布时间】:2014-09-10 06:21:35
【问题描述】:

正如 WPF 经常发生的那样,我可能会以错误的方式处理事情,但我有以下情况:

我想根据 DataTrigger 应用样式,但您不能从样式内部更改样式:

<Button>
   <Button.Style>
      <Style BasedOn="SomeStyle">
         <Style.Triggers>
            <DataTrigger ...>
               <Setter Property="Style" Value="OtherStyle" /> <---- NO CAN DO

确实合乎逻辑,但我想避免重复 same 设置器,只是因为我的触发条件发生了变化:

<Button>
   <Button.Style>
      <Style BasedOn="SomeStyle">
         <Style.Triggers>
            <DataTrigger Binding="{Binding X}" Value="Condition1">
               <Setter Property="A" Value="1" /> 
               <Setter Property="B" Value="1" /> 
               <etc...>
(...)

<Button>
   <Button.Style>
      <Style BasedOn="SomeStyle">
         <Style.Triggers>
            <DataTrigger Binding="{Binding X}" Value="Condition2">
               <Setter Property="A" Value="1" /> 
               <Setter Property="B" Value="1" /> 
               <etc...>

还有什么东西可以让我把DataTrigger放进去,这样我就可以从里面改变样式了吗?或者另一种方式:避免重复样式信息?

【问题讨论】:

  • 您想在两个不同的条件下应用相同的设置器集吗?纠正我我的看法不同。更改样式将无济于事,因为一旦更改,它将立即恢复。最后,您可以使用数据触发器来更改所需元素的父元素样式中的元素样式。
  • @pushpraj,是的,同样的二传手。我会尝试更新

标签: wpf xaml


【解决方案1】:

以下是如何根据数据触发器更改元素样式的示例:

<StackPanel>
    <Control Focusable="False">
        <Control.Template>
            <ControlTemplate>
                <!--resources-->
                <ControlTemplate.Resources>
                    <Style TargetType="Button" x:Key="primary">
                        <Setter Property="Content" Value="Primary style"/>
                    </Style>
                    <Style TargetType="Button" x:Key="secondary">
                        <Setter Property="Content" Value="Secondary style"/>
                    </Style>
                </ControlTemplate.Resources>
                <!--content-->
                <Button Style="{StaticResource primary}" x:Name="button"/>
                <!--triggers-->
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}" Value="true">
                        <Setter TargetName="button" Property="Style" Value="{StaticResource secondary}"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding IsKeyboardFocusWithin,RelativeSource={RelativeSource Self}}" Value="true">
                        <Setter TargetName="button" Property="Style" Value="{StaticResource secondary}"/>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Control.Template>
    </Control>
    <Button Content="A normal button"/>
</StackPanel>

在此示例中,Control 是一个包装器元素,它将在其控制模板中承载所需的元素。如果您希望通过名称访问它,则它必须在控制模板中。在控件模板的触发器中定义了一组数据触发器,它将根据需要将样式应用于所需元素(按钮)。

我没有找到避免重复设置器的方法。也许交换/应用样式的能力可以帮助您获得相同的结果。

如果您不想使用控件模板方法,您可以使用附加属性或元素中未使用的Tag 属性。在本例中,我们将利用两种方式绑定来实现相同的结果。

例子:

<StackPanel>
    <Grid>
        <!--content-->
        <Button Style="{Binding Tag,RelativeSource={RelativeSource FindAncestor,AncestorType=Grid}}"/>
        <Grid.Style>
            <Style TargetType="Grid">
                <!--resources-->
                <Style.Resources>
                    <Style TargetType="Button" x:Key="primary">
                        <Setter Property="Content" Value="Primary style"/>
                    </Style>
                    <Style TargetType="Button" x:Key="secondary">
                        <Setter Property="Content" Value="Secondary style"/>
                    </Style>
                </Style.Resources>
                <Setter Property="Tag" Value="{StaticResource primary}"/>
                <!--triggers-->
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}" Value="true">
                        <Setter Property="Tag" Value="{StaticResource secondary}"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding IsKeyboardFocusWithin,RelativeSource={RelativeSource Self}}" Value="true">
                        <Setter Property="Tag" Value="{StaticResource secondary}"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Grid.Style>
    </Grid>
    <Button Content="A normal button"/>
</StackPanel>

尝试一下,看看这是否能帮助您达到预期的效果。

【讨论】:

  • 不情愿的赞成票。这两种解决方案看起来都很丑陋,尽管我知道这不是你的错:(
猜你喜欢
  • 1970-01-01
  • 2019-10-11
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 2023-01-13
  • 2012-11-08
  • 2018-06-14
  • 1970-01-01
相关资源
最近更新 更多