Кнопка переключения WPF с анимированным содержимым

#wpf #image #templates #togglebutton

#wpf #изображение #шаблоны #кнопка переключения

Вопрос:

Я хотел создать кнопку переключения, которая содержит два серых зубчатых колеса, когда она не отмечена, и два красных вращающихся зубца, когда она нажата. Я создал шаблон с триггерами, которые проверяют свойство 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>
  

Ответ №1:

Причина, по которой это происходит, заключается в том, что изображения в триггерах заморожены и не являются общими, поэтому будет только один экземпляр.

Поскольку это довольно статичный дизайн, альтернативным подходом было бы заменить 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>
  

Комментарии:

1. Работает как заклинание. Я не думал делать это таким образом… Большое спасибо!