Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate IsChecked property?

I have custom control with number of ToggleButtons:

<Style TargetType="{x:Type local:ISA88Buttons}">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type local:ISA88Buttons}">
          <Border x:Name="PART_Border" 
                  Background="{TemplateBinding Background}"
                  BorderBrush="{TemplateBinding BorderBrush}"
                  BorderThickness="{TemplateBinding BorderThickness}">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="ISA88States">
...
                 <VisualState x:Name="AbortingState" Storyboard="{StaticResource sbAbortingState}" />
                <VisualState x:Name="AbortedState" Storyboard="{StaticResource sbAbortedState}" />
...
              </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>

<StackPanel Margin="1" 
                        HorizontalAlignment="Center"
                        Orientation="Horizontal">
...
<ToggleButton x:Name="PART_Button_Abort" 
                            Margin="1"
                            IsChecked="False"
                            IsThreeState="True"
                            Tag="Abort">
                <ToggleButton.Style>
                  <Style TargetType="{x:Type ToggleButton}">
                    <Setter Property="OverridesDefaultStyle" Value="True" />
                    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
                    <Setter Property="Template">
                      <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ToggleButton}">
                          <Border x:Name="border" 
                                  Width="{TemplateBinding Width}"
                                  Height="{TemplateBinding Height}"
                                  Background="{StaticResource NormalAbortButtonDrawingBrush}" />
                          <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="False">
                              <Setter TargetName="border" Property="Background" Value="{StaticResource DisabledAbortButtonDrawingBrush}" />
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                              <Setter TargetName="border" Property="Background" Value="{StaticResource MouseOverAbortButtonDrawingBrush}" />
                            </Trigger>
                            <MultiTrigger>
                              <MultiTrigger.Conditions>
                                <Condition Property="IsEnabled" Value="True" />
                                <Condition Property="IsChecked" Value="True" />
                              </MultiTrigger.Conditions>
                              <MultiTrigger.Setters>
                                <Setter TargetName="border" Property="Background" Value="{StaticResource PressedAbortButtonDrawingBrush}" />
                              </MultiTrigger.Setters>
                            </MultiTrigger>
                            <MultiTrigger>
                              <MultiTrigger.Conditions>
                                <Condition Property="IsEnabled" Value="True" />
                                <Condition Property="IsChecked" Value="{x:Null}" />
                              </MultiTrigger.Conditions>
                              <MultiTrigger.EnterActions>
                                <BeginStoryboard x:Name="sb">
                                  <Storyboard RepeatBehavior="Forever">
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="border" Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource PressedAbortButtonDrawingBrush}" />
                                        <DiscreteObjectKeyFrame KeyTime="00:00:0.25" Value="{StaticResource NormalAbortButtonDrawingBrush}" />
                                        <DiscreteObjectKeyFrame KeyTime="00:00:0.5" Value="{StaticResource PressedAbortButtonDrawingBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                  </Storyboard>
                                </BeginStoryboard>
                              </MultiTrigger.EnterActions>
                            </MultiTrigger>
                          </ControlTemplate.Triggers>
                        </ControlTemplate>
                      </Setter.Value>
                    </Setter>
                  </Style>
                </ToggleButton.Style>
              </ToggleButton>
...
</StackPanel>
          </Border>
</ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

And Storyboards:

  <Storyboard x:Key="sbAbortingState">     
      <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Button_Abort" Storyboard.TargetProperty="(ToggleButton.IsChecked)">
          <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Null}" />
          </ObjectAnimationUsingKeyFrames>
  </Storyboard>

  <Storyboard x:Key="sbAbortedState">
       <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Button_Abort" Storyboard.TargetProperty="(ToggleButton.IsChecked)">
          <DiscreteObjectKeyFrame KeyTime="0" Value="True" />
          </ObjectAnimationUsingKeyFrames>
  </Storyboard>

When my control in Aborting state, button Abort is blinking, but when i change state to Aborted the error is raises:

Cannot animate the 'IsChecked' property on a 'System.Windows.Controls.Primitives.ToggleButton' using a 'System.Windows.Media.Animation.ObjectAnimationUsingKeyFrames'

How can I animate this property using Storyboard between three values: true, false and {x:Null}, not only true and false.

like image 802
Y.Yanavichus Avatar asked Feb 07 '11 04:02

Y.Yanavichus


2 Answers

The problem is that you shouldn't really be setting a Boolean value using a ObjectAnimationUsingKeyFrames animation, rather it should be a BooleanAnimationUsingKeyFrames animation with a DiscreteBooleanKeyFrame keyframe.

So your markup would be:

<BooleanAnimationUsingKeyFrames Storyboard.TargetName="Button" Storyboard.TargetProperty="(ToggleButton.IsChecked)">
      <DiscreteBooleanKeyFrame KeyTime="0" Value="{x:Null}" />
</BooleanAnimationUsingKeyFrames>

<BooleanAnimationUsingKeyFrames Storyboard.TargetName="Button" Storyboard.TargetProperty="(ToggleButton.IsChecked)">
      <DiscreteBooleanKeyFrame KeyTime="0" Value="True" />
</BooleanAnimationUsingKeyFrames>

<BooleanAnimationUsingKeyFrames Storyboard.TargetName="Button" Storyboard.TargetProperty="(ToggleButton.IsChecked)">
      <DiscreteBooleanKeyFrame KeyTime="0" Value="False" />
</BooleanAnimationUsingKeyFrames>
like image 88
LordWilmore Avatar answered Sep 20 '22 02:09

LordWilmore


I found solution. If you want to set bool? property in XAML you should do so:

<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Button" Storyboard.TargetProperty="(ToggleButton.IsChecked)">
      <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Null}" />
</ObjectAnimationUsingKeyFrames>

<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Button" Storyboard.TargetProperty="(ToggleButton.IsChecked)">
      <DiscreteObjectKeyFrame KeyTime="0">
        <DiscreteObjectKeyFrame.Value>
          <sys:Boolean>True</sys:Boolean>
        </DiscreteObjectKeyFrame.Value>
      </DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>

<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Button" Storyboard.TargetProperty="(ToggleButton.IsChecked)">
      <DiscreteObjectKeyFrame KeyTime="0">
        <DiscreteObjectKeyFrame.Value>
          <sys:Boolean>False</sys:Boolean>
        </DiscreteObjectKeyFrame.Value>
      </DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
like image 37
Y.Yanavichus Avatar answered Sep 22 '22 02:09

Y.Yanavichus