带有动画内容的 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>