以下是一个示例,演示如何基于数据触发器更改元素的样式:
<StackPanel>
<Control Focusable="False">
<Control.Template>
<ControlTemplate>
<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>
<Button Style="{StaticResource primary}" x:Name="button"/>
<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>
<Button Style="{Binding Tag,RelativeSource={RelativeSource FindAncestor,AncestorType=Grid}}"/>
<Grid.Style>
<Style TargetType="Grid">
<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}"/>
<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>
试一试,看看这是否有助于你实现所期望的结果。