Impostare un trigger quando TextBox.Text == string.Empty
Stamattina mi è venuta una piccola idea facilmente realizzabile in WPF. Immaginatevi una TextBox su una Window nella quale l’utente può digitare una qualsivoglia informazione. Supponiamo adesso di voler evidenziare in qualche modo quando la TextBox è vuota, magari per dire all’utente che quella casella è obbligatoria e che va riempita per forza.
La prima cosa che ho pensato è di impostare un trigger sulla TextBox stessa. Lo XAML iniziale è:
<TextBox Height="20" VerticalAlignment="Top" Margin="6" Name="txtUsername" />
Il trigger va impostato nelle risorse associate alla TextBox, per cui lo XAML va spezzato in questo modo:
<TextBox Height="20" VerticalAlignment="Top" Margin="6" Name="txtUsername"> <TextBox.Resources> </TextBox.Resources> </TextBox>
Nel blocco <TextBox.Resources></TextBox.Resources> inseriamo lo stile che contiene il trigger:
<Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="Text.Length" Value="0"> <Setter Property="Background" Value="Red"/> </Trigger> </Style.Triggers> </Style>
La logica è: quando la proprietà Text.Length è 0, allora il Background della TextBox deve diventare rosso. Ma il codice non compila: l’errore è : Value ‘Text.Length’ cannot be assigned to property ‘Property’. Ma possiamo girare la frittata in un’altra maniera. Se riusciamo a far scatenare il trigger quando la proprietà Text == string.Empty, otteniamo esattamente lo stesso risultato. Ok, ragioniamo.
Empty è una proprietà statica della classe String. String è definita dentro il namespace System. L’assembly è mscorlib.dll. Ok, detto questo, procediamo. Importiamo nello XAML l’assembly che ci serve:
xmlns:s="clr-namespace:System;assembly=mscorlib.dll"
Il blocco qui sopra va incollato nella definizione della Window. A questo punto il trigger può essere impostato in questo modo (riporto l’intero blocco XAML che definisce la TextBox, che così potete copiare ed incollare facilmente):
<TextBox Height="20" VerticalAlignment="Top" Margin="6" Name="txtUsername"> <TextBox.Resources> <Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="Text" Value="{x:Static s:String.Empty}"> <Setter Property="Background" Value="Red"/> </Trigger> </Style.Triggers> </Style> </TextBox.Resources> </TextBox>
In pratica, utilizzo x:Static per accedere alla proprietà statica Empty della classe String. Quando la condizione è verificata, il trigger si scatena ed il Background della TextBox diventa rosso. Ricordo che ci pensa WPF a riportare il Background allo stato originario nel momento in cui la condizione del trigger diventa falsa.
La cosa più comoda, IMHO, è spostare la definizione dello stile dentro il blocco <Application.Resources></Application.Resources> del file App.xaml, in modo tale che lo stile sia accessibile non solo a quella particolare TextBox, ma a qualsiasi TextBox della nostra applicazione alla quale decidiamo di associare quello stile. Mi spiego meglio: apriamo il file App.xaml e fra le risorse incolliamo questo blocco XAML:
<Style x:Key="mandatory" TargetType="TextBox"> <Style.Triggers> <Trigger Property="Text" Value="{x:Static s:String.Empty}"> <Setter Property="Background" Value="Red"/> </Trigger> </Style.Triggers> </Style>
Da notare che ho associato una Key allo stile, oltre che definire il Type sui quali possiamo associare lo stile stesso. Lo stile ha una Key = “mandatory”. Adesso possiamo semplicemente prendere tutte le TextBox che vogliamo rendere obbligatorie (perlomeno visivamente) e dire loro di usare quello stile particolare. Ad esempio:
<TextBox Height="20" VerticalAlignment="Top" Margin="6" Name="txtUsername" Style="{StaticResource mandatory}">
Ed il gioco è fatto. Ricordo che non c’è alcuna logica di validazione: l’utente può spostarsi da un controllo all’altro e via dicendo. Quello che abbiamo fatto ha solo un riscontro visivo e nulla di più.