带有动画内容的 WPF 切换按钮
WPF Toggle button with animated content
我想创建一个切换按钮,它在未选中时包含两个灰色齿轮,在按下时包含两个红色旋转齿轮。我创建了一个模板,其中包含触发器检查 IsChecked 属性 并相应地设置按钮的内容。
它似乎工作得很好,但是当我在页面上添加两个按钮时,第一个按钮似乎是空白的(没有图像)。好像只能同时打开或关闭一个按钮。
我做错了什么?
<SolidColorBrush x:Key="CogwheelButton.Border.Color" Color="Transparent"/>
<SolidColorBrush x:Key="CogwheelButton.Background.Color" Color="Transparent"/>
<Style x:Key="CogwheelButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="{StaticResource CogwheelButton.Background.Color}"/>
<Setter Property="BorderBrush" Value="{StaticResource CogwheelButton.Border.Color}"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="0" BorderBrush="Transparent">
<Grid>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Control.Visibility" Value="Hidden"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Grid Width="29" Height="35" VerticalAlignment="Center" HorizontalAlignment="Center">
<Image Source="/Resources/CogwheelRed.png" VerticalAlignment="Top" HorizontalAlignment="Left" Width="20" Height="20" Margin="0" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Control.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation AutoReverse="False"
Duration="0:0:3"
From="0"
RepeatBehavior="Forever"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
To="360" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
<Image Source="/Resources/CogwheelRed.png" VerticalAlignment="Top" HorizontalAlignment="Left" Width="20" Height="20" Margin="9,15,0,0" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Control.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation AutoReverse="False"
Duration="0:0:3"
From="0"
RepeatBehavior="Forever"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
To="-360" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content">
<Setter.Value>
<Grid Width="29" Height="35" VerticalAlignment="Center" HorizontalAlignment="Center">
<Image Source="/Resources/CogwheelGray.png" VerticalAlignment="Top" HorizontalAlignment="Left" Width="20" Height="20" Margin="0" Stretch="Uniform"/>
<Image Source="/Resources/CogwheelGray.png" VerticalAlignment="Top" HorizontalAlignment="Left" Width="20" Height="20" Margin="9,15,0,0" Stretch="Uniform" />
</Grid>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
出现这种情况的原因是触发器中的图像被冻结且未共享,因此只有一个实例。
由于这是一个非常静态的设计,另一种方法是用实际图像替换 ContentPresenter,然后只更改它们的源并在 IsChecked 上触发动画。
这是工作 XAML:
<SolidColorBrush x:Key="CogwheelButton.Border.Color" Color="Transparent" />
<SolidColorBrush x:Key="CogwheelButton.Background.Color" Color="Transparent" />
<Style x:Key="CogwheelButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="{StaticResource CogwheelButton.Background.Color}" />
<Setter Property="BorderBrush" Value="{StaticResource CogwheelButton.Border.Color}" />
<Setter Property="Padding" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="Transparent"
BorderThickness="0">
<Grid
Width="29"
Height="35"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Image x:Name="Cog1"
Width="20"
Height="20"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
RenderTransformOrigin="0.5,0.5"
Source="/Resources/CogwheelGray.png"
Stretch="Uniform">
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
</Image>
<Image x:Name="Cog2"
Width="20"
Height="20"
Margin="9,15,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
RenderTransformOrigin="0.5,0.5"
Source="/Resources/CogwheelGray.png"
Stretch="Uniform">
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
</Image>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Control.Visibility" Value="Hidden" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Cog1" Property="Source" Value="/Resources/CogwheelRed.png" />
<Setter TargetName="Cog2" Property="Source" Value="/Resources/CogwheelRed.png" />
<Trigger.EnterActions>
<BeginStoryboard x:Name="CogAnimation">
<Storyboard>
<DoubleAnimation
AutoReverse="False"
RepeatBehavior="Forever"
Storyboard.TargetName="Cog1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
From="0"
To="360"
Duration="0:0:3" />
<DoubleAnimation
AutoReverse="False"
RepeatBehavior="Forever"
Storyboard.TargetName="Cog2"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
From="0"
To="-360"
Duration="0:0:3" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="CogAnimation" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我想创建一个切换按钮,它在未选中时包含两个灰色齿轮,在按下时包含两个红色旋转齿轮。我创建了一个模板,其中包含触发器检查 IsChecked 属性 并相应地设置按钮的内容。
它似乎工作得很好,但是当我在页面上添加两个按钮时,第一个按钮似乎是空白的(没有图像)。好像只能同时打开或关闭一个按钮。
我做错了什么?
<SolidColorBrush x:Key="CogwheelButton.Border.Color" Color="Transparent"/>
<SolidColorBrush x:Key="CogwheelButton.Background.Color" Color="Transparent"/>
<Style x:Key="CogwheelButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="{StaticResource CogwheelButton.Background.Color}"/>
<Setter Property="BorderBrush" Value="{StaticResource CogwheelButton.Border.Color}"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="0" BorderBrush="Transparent">
<Grid>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Control.Visibility" Value="Hidden"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Grid Width="29" Height="35" VerticalAlignment="Center" HorizontalAlignment="Center">
<Image Source="/Resources/CogwheelRed.png" VerticalAlignment="Top" HorizontalAlignment="Left" Width="20" Height="20" Margin="0" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Control.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation AutoReverse="False"
Duration="0:0:3"
From="0"
RepeatBehavior="Forever"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
To="360" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
<Image Source="/Resources/CogwheelRed.png" VerticalAlignment="Top" HorizontalAlignment="Left" Width="20" Height="20" Margin="9,15,0,0" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Control.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation AutoReverse="False"
Duration="0:0:3"
From="0"
RepeatBehavior="Forever"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
To="-360" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content">
<Setter.Value>
<Grid Width="29" Height="35" VerticalAlignment="Center" HorizontalAlignment="Center">
<Image Source="/Resources/CogwheelGray.png" VerticalAlignment="Top" HorizontalAlignment="Left" Width="20" Height="20" Margin="0" Stretch="Uniform"/>
<Image Source="/Resources/CogwheelGray.png" VerticalAlignment="Top" HorizontalAlignment="Left" Width="20" Height="20" Margin="9,15,0,0" Stretch="Uniform" />
</Grid>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
出现这种情况的原因是触发器中的图像被冻结且未共享,因此只有一个实例。
由于这是一个非常静态的设计,另一种方法是用实际图像替换 ContentPresenter,然后只更改它们的源并在 IsChecked 上触发动画。
这是工作 XAML:
<SolidColorBrush x:Key="CogwheelButton.Border.Color" Color="Transparent" />
<SolidColorBrush x:Key="CogwheelButton.Background.Color" Color="Transparent" />
<Style x:Key="CogwheelButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="{StaticResource CogwheelButton.Background.Color}" />
<Setter Property="BorderBrush" Value="{StaticResource CogwheelButton.Border.Color}" />
<Setter Property="Padding" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="Transparent"
BorderThickness="0">
<Grid
Width="29"
Height="35"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Image x:Name="Cog1"
Width="20"
Height="20"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
RenderTransformOrigin="0.5,0.5"
Source="/Resources/CogwheelGray.png"
Stretch="Uniform">
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
</Image>
<Image x:Name="Cog2"
Width="20"
Height="20"
Margin="9,15,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
RenderTransformOrigin="0.5,0.5"
Source="/Resources/CogwheelGray.png"
Stretch="Uniform">
<Image.RenderTransform>
<RotateTransform Angle="0" />
</Image.RenderTransform>
</Image>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Control.Visibility" Value="Hidden" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Cog1" Property="Source" Value="/Resources/CogwheelRed.png" />
<Setter TargetName="Cog2" Property="Source" Value="/Resources/CogwheelRed.png" />
<Trigger.EnterActions>
<BeginStoryboard x:Name="CogAnimation">
<Storyboard>
<DoubleAnimation
AutoReverse="False"
RepeatBehavior="Forever"
Storyboard.TargetName="Cog1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
From="0"
To="360"
Duration="0:0:3" />
<DoubleAnimation
AutoReverse="False"
RepeatBehavior="Forever"
Storyboard.TargetName="Cog2"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
From="0"
To="-360"
Duration="0:0:3" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="CogAnimation" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>