Oggi nel preparare una demo sulle animazioni di WPF ho pensato di creare un animazione che facesse lampeggiare un controllo in una finestra, operazione a prima vista banale...

Problema 1: La visibilità di un controllo è un enumerato di tipo Visibility come lo "animiamo"? Fortunatamente ho scoperto la presenza di una generica animazione ObjectAnimationUsingKeyFrames percui l'operazione è stata abbastanza semplice:

   1:  <Window.Resources>
   2:      <ObjectAnimationUsingKeyFrames Duration="0:0:1" x:Key="an1" RepeatBehavior="Forever">
   3:        <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
   4:        <DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="{x:Static Visibility.Hidden}" />
   5:      </ObjectAnimationUsingKeyFrames>
   6:  </Window.Resources>
 
A questo punto è possibile utilizzare l'animazione in questo modo:
 
   1:  //Fa lampeggiare btn1
   2:  ObjectAnimationUsingKeyFrames an = this.FindResource("an1") as ObjectAnimationUsingKeyFrames;
   3:  btn1.BeginAnimation(Button.VisibilityProperty, an);
   4:   
   5:  //Annulla il lampeggio di btn1
   6:  btn1.BeginAnimation(Button.VisibilityProperty, null);
 
Ok, ma se volessi utilizzare l'animazione all'interno di uno stile?
 
Problema 2: Quando il controllo diventa invisibile, il mouse non viene più segnalato come "over the control" 
e quindi scatta il trigger che riporta il controllo nello stato iniziale.
Bisogna quindi agire sulla proprietà Opacity. 
 
   1:  <Style x:Key="BlinkingElement" TargetType="{x:Type Control}">
   2:        <Style.Triggers>
   3:          <Trigger Property="IsMouseOver" Value="True">
   4:            <Trigger.EnterActions>
   5:              <BeginStoryboard>
   6:                <Storyboard>
   7:                  <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" 
   8:                                       Duration="0:0:1" RepeatBehavior="Forever" AutoReverse="True">
   9:                    <DiscreteDoubleKeyFrame  Value="1" />
  10:                    <DiscreteDoubleKeyFrame  KeyTime="0:0:0.5" Value="0" />
  11:                  </DoubleAnimationUsingKeyFrames>
  12:                </Storyboard>
  13:              </BeginStoryboard>
  14:            </Trigger.EnterActions>
  15:            <Trigger.ExitActions>
  16:              <BeginStoryboard>
  17:                <Storyboard>
  18:                  <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
  19:                    <DiscreteDoubleKeyFrame Value="1" />
  20:                  </DoubleAnimationUsingKeyFrames>
  21:                </Storyboard>
  22:              </BeginStoryboard>
  23:            </Trigger.ExitActions>
  24:          </Trigger>
  25:        </Style.Triggers>
  26:      </Style>
 
A questo punto grazie all'ereditarietà degli stili possiamo creare uno stile "lampeggiante" semplicemente scrivendo:
 
   1:  <Style TargetType="{x:Type Button}" BasedOn="{StaticResource BlinkingElement}" />

Per ottenere dei button che lampeggiano quando il mouse sta sopra di loro.

Forse avrei fatto meglio a cercare un esempio più semplice... smile_wink