Attraverso gli stili statici è possibile centralizzare in un unico punto il look & feel di un applicazione col grande vantaggio che, agendo semplicemente sullo stile, possiamo "rivoluzionare" la user interface del nostro progetto, e questo gli sviluppatori WEB lo sanno benissimo...
Gli stili posso però anche essere dinamici, ovvero applicati solo al verificarsi di determinate condizioni quali
- Il variare di una proprietà.
- Lo scatenarsi di un evento.
- Il cambio di valore di una proprietà Databound.
esempio
<Style x:Key="DerivedStyle2" BasedOn="{StaticResource Style1}">
<Setter Property="Button.Background" Value="Lime" />
<Style.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Button.Background" Value="Blue" />
<Setter Property="Button.Foreground" Value="White" />
<Setter Property="Button.FontSize" Value="14" />
</Trigger>
</Style.Triggers>
</Style>
In questo caso ho definito uno stile "DerivedStyle2" il quale eredita da Style1 e imposta il colore di sfondo di un button a Lime, ho inoltre aggiunto alla collezione Triggers esposta dallo Style un oggetto Trigger il quale tiene sotto controllo una dependency property (IsMouseOver) e quando questa assume un determinato valore applica i setters ad esso associati.
Una interessante novità è che il trigger si occupa di cachare i valori delle proprietà che andrà a modificare rispritinandoli non appena la condizione del trigger non sarà più vera (IsMouseOver=False).
Nel caso la condizione da monitorare per l'applicazione dello stile sia più complessa è possibile usare un Multitrigger.
<Style x:Key="DerivedStyle3" BasedOn="{StaticResource Style1}">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Button.IsMouseOver" Value="True"/>
<Condition Property="Button.IsCancel" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Button.FontSize" Value="20" />
<Setter Property="Button.FontWeight" Value="Bold" />
</MultiTrigger>
</Style.Triggers>
</Style>
In questo caso FontSize e FontWeigth verranno applicati solo entrambe le proprietà IsMouseOver e IsCancel del pulsante che è associato a questo stile sono vere.
Ecco un esempio di EventTrigger
<Style x:Key="EventBased">
<Style.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation AutoReverse="True" From="0" To="45" Storyboard.TargetProperty="(Button.RenderTransform).(RotateTransform.Angle)" Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
Pulsante che usa lo stile sopra definito...
<Button Style="{StaticResource EventBased}" Content="11" >
<Button.RenderTransform>
<RotateTransform Angle="0" />
</Button.RenderTransform>
</Button> In questo caso quello che bisogna specificare è l'evento che vogliamo monitorare (MouseEnter) e definire le azioni associate che, per questo specifico trigger, devono essere delle TriggerActions ovvero non è possibile usare direttamente dei Setters anche perchè gli EventTriggers non esiste il concetto di "fine evento" quindi non è possibile ripristinare il valore originale della proprietà automaticamente.
L'azione che questo EventTrigger esegue allo scattare del MouseEnter è modificare da 0 a 45 e viceversa l'angolo del RotateTranform associato al pulsante 11 col risultato che il pulsante si mette a penzolare.
Giusto per completezza, un esempio di DataTrigger:
<Style x:Key="DataBased">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, ElementName=txt1}" Value="ok">
<Setter Property="TextBox.Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
<TextBox Height="50" Name="txt1" Style="{StaticResource DataBased}">Type ok here...</TextBox>
Il DataTrigger scatta quando il valore della proprietà (Text in questo caso) assume il valore "ok", modificandone il colore di sfondo.
Qui trovate un esempio che raggruppa gli snippets dei post relativi agli stili.