Search code examples
wpfanimationdatatemplateitemscontrol

WPF Animations Not Working In Items Control


Below is a ItemsControl that I have defined with a DataTemplate. The trouble I am having is getting the Animations to play. In it's current form the Checkbox's show correctly and the Border changes to Blue when you mouse over each item but when you mouse out the border stays blue. Reordering the triggers collection makes different actions work or break and if I remove the animations and replace them with Setters then things work as expected. What am I missing here? Any help would be very much appreciated - thanks.

<ItemsControl ItemsSource="{Binding ToolBarsBackingStore}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Border Name="OutterBorder"
              BorderThickness="1"
              CornerRadius="5"
              Background="{StaticResource StaticBackgroundBrush}"
              HorizontalAlignment="Center"
              VerticalAlignment="Center">

        <Border.BorderBrush>
          <SolidColorBrush x:Name="HighlightBorder"
                           Color="{StaticResource StaticBackground}" />
        </Border.BorderBrush>

      <StackPanel Orientation="Horizontal"
                  Height="16">

        <CheckBox Name="ShowCheck"
                  Style="{StaticResource ToolTrayMenuCheckBoxStyle}"
                  Margin="3 0 0 0"
                  IsHitTestVisible="False"
                  IsChecked="{Binding Path=Visibility,
                  Converter={StaticResource VisibilityToCheckedConverter}}">

         <CheckBox.Foreground>
           <SolidColorBrush x:Name="CheckColor"
                            Color="{StaticResource StaticBackground}" />
         </CheckBox.Foreground>
       </CheckBox>

       <TextBlock Width="80"
                  Margin="10 0 0 0"
                  Text="{Binding Path=Name,
                  Mode=OneTime}"
                  TextAlignment="Left"
                  TextTrimming="CharacterEllipsis"
                  SnapsToDevicePixels="True"
                  Foreground="White" />
     </StackPanel>
   </Border>

  <DataTemplate.Triggers>
    <Trigger SourceName="ShowCheck"
             Property="IsChecked"
             Value="True">

      <Setter TargetName="ShowCheck"
              Property="Foreground"
              Value="#777777" />
    </Trigger> 

    <MultiDataTrigger>
      <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Path=IsMouseOver,
                             ElementName=OutterBorder}"
                             Value="False"/>
        <Condition Binding="{Binding Path=IsChecked,
                                     ElementName=ShowCheck}"
                                     Value="True"/>
     </MultiDataTrigger.Conditions>

     <MultiDataTrigger.EnterActions>
       <BeginStoryboard>
         <Storyboard TargetName="HighlightBorder">
           <ColorAnimation Storyboard.TargetProperty="Color"
                           To="Black"
                           Duration="0:0:0.3" />
         </Storyboard>
       </BeginStoryboard>

       <BeginStoryboard>
         <Storyboard TargetName="CheckColor">
           <ColorAnimation Storyboard.TargetProperty="Color"
                           To="#777777"
                           Duration="0:0:0.3"/>
         </Storyboard>
       </BeginStoryboard>
     </MultiDataTrigger.EnterActions>
   </MultiDataTrigger>


   <MultiDataTrigger>
     <MultiDataTrigger.Conditions>

       <Condition Binding="{Binding Path=IsMouseOver,
                            ElementName=OutterBorder}"
                  Value="True"/>

       <Condition Binding="{Binding Path=IsChecked,
                                    ElementName=ShowCheck}"
                  Value="True" />
     </MultiDataTrigger.Conditions>

   <MultiDataTrigger.EnterActions>
     <BeginStoryboard>
       <Storyboard TargetName="HighlightBorder">
         <ColorAnimation Storyboard.TargetProperty="Color"
                         To="CornflowerBlue"
                         Duration="0:0:0.3"/> 
       </Storyboard>
     </BeginStoryboard>

     <BeginStoryboard>
       <Storyboard TargetName="CheckColor">
         <ColorAnimation Storyboard.TargetProperty="Color"
                         To="White"
                         Duration="0:0:0.3" />
       </Storyboard>
     </BeginStoryboard>
   </MultiDataTrigger.EnterActions>
 </MultiDataTrigger>


 <MultiDataTrigger>
   <MultiDataTrigger.Conditions>

     <Condition Binding="{Binding Path=IsMouseOver, 
                                  ElementName=OutterBorder}"
                Value="True"/>

     <Condition Binding="{Binding Path=IsChecked, 
                                  ElementName=ShowCheck}"
                Value="False"/>

   </MultiDataTrigger.Conditions>

   <MultiDataTrigger.EnterActions>
     <BeginStoryboard>
       <Storyboard TargetName="HighlightBorder">
         <ColorAnimation Storyboard.TargetProperty="Color"
                         To="CornflowerBlue"
                         Duration="0:0:0.3"/> 
       </Storyboard>
     </BeginStoryboard>
   </MultiDataTrigger.EnterActions>
 </MultiDataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Solution

  • Your animation storyboards are stacking up. You need to remove them in the ExitActionsof the triggers. Name your BeginStoryboardinstances and use RemoveStoryboardin the ExitActionsto clear the storyboard and allow another storyboard to work. For example:

    <MultiDataTrigger>
      <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Path=IsMouseOver,
                             ElementName=OutterBorder}"
                             Value="False"/>
        <Condition Binding="{Binding Path=IsChecked,
                                     ElementName=ShowCheck}"
                                     Value="True"/>
     </MultiDataTrigger.Conditions>
    
     <MultiDataTrigger.EnterActions>
    
       <!-- Give BeginStoryboard a name -->
       <BeginStoryboard x:Name="MouseNotOverAndChecked">
    
         <Storyboard TargetName="HighlightBorder">
           <ColorAnimation Storyboard.TargetProperty="Color"
                           To="Black"
                           Duration="0:0:0.3" />
         </Storyboard>
       </BeginStoryboard>
    
       <BeginStoryboard>
         <Storyboard TargetName="CheckColor">
           <ColorAnimation Storyboard.TargetProperty="Color"
                           To="#777777"
                           Duration="0:0:0.3"/>
         </Storyboard>
       </BeginStoryboard>
     </MultiDataTrigger.EnterActions>
    
     <!-- Use the exit actions to remove the storyboard. Use the name given above -->
     <MultiDataTrigger.ExitActions>
         <RemoveStoryboard BeginStoryboardName="MouseNotOverAndChecked" />
     </MultiDataTrigger.ExitActions>