Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1908, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Xamarin.Forms e la validazione dell'input lato client - parte 2

Nella prima parte abbiamo implementato dei behavior da utilizzare per validare l'input dell'utente, ma quella è l'infrastruttura che ancora non abbiamo visto in azione, perché da collegare alla UI e quindi allo XAML.

L'obiettivo è mostrare anche una Label di colore rosso, oltre alla logica applicata dal behavior sulle Entry. Per farlo devo convertire lo stato del behavior in un oggetto bool per capire se lo stato del controllo è valido oppure no e, conseguentemente, mostrare o nascondere la label. Mi serve quindi un converter, tipo di oggetto caro a chi conosce XAML e che si implementa sempre attraverso l'interfaccia IValueConverter, che in questa piattaforma è esposta dal namespace Xamarin.Forms. Eccolo:

public class BoolToObjectConverter<T> : IValueConverter
{
    public T FalseObject { setget; }
 
    public T TrueObject { setget; }
 
    public object Convert(object value, Type targetType,
                          object parameter, CultureInfo culture)
    {
        return (bool)value ? this.TrueObject : this.FalseObject;
    }
 
    public object ConvertBack(object value, Type targetType,
                              object parameter, CultureInfo culture)
    {
        return ((T)value).Equals(this.TrueObject);
    }
}

Successivamente, nello XAML della pagina in cui intendiamo utilizzare i behavior, definiremo 3 stili per il controllo Label. Il primo, uno stile base che stabilisce corsivo e font small. Due stili, poi, che stabiliscono come la Label deve apparire a seconda che la proprietà IsValid nei behavior sia vera oppure falsa, quindi se la Label in questione deve o meno essere visibile. Eccoli:

  <Style x:Key="baseStyle" TargetType="Label">
    <Setter Property="FontSize" Value="Small" />
    <Setter Property="FontAttributes" Value="Italic" />
  </Style>
 
  <converters:BoolToObjectConverter x:Key="boolToStringEmpty"
                                   x:TypeArguments="Style">
    <converters:BoolToObjectConverter.FalseObject>
      <Style TargetType="Label" BasedOn="{StaticResource baseStyle}">
        <Setter Property="TextColor" Value="Red" />
        <Setter Property="Text" Value="Field cannot be empty" />
      </Style>
    </converters:BoolToObjectConverter.FalseObject>
 
    <converters:BoolToObjectConverter.TrueObject>
      <Style TargetType="Label" BasedOn="{StaticResource baseStyle}">
        <Setter Property="TextColor" Value="Default" />
        <Setter Property="Text" Value="" />
      </Style>
    </converters:BoolToObjectConverter.TrueObject>
  </converters:BoolToObjectConverter>
Nota: in Xamarin.Forms 2.3.0.49 è stato introdotto il supporto ai Resource dictionary che prima non c'era, quindi può essere eventualmente utile da tenere a mente.

Ottimo, a questo punto ho tutto quello che mi serve. Dichiaro un namespace XML per fare riferimento alla classe che definisce il converter e uno per fare riferimento al namespace che definisce i behavior, e poi vado ad utilizzare i behavior così:

  <ContentPage.Resources>
    <ResourceDictionary MergedWith="styles:SharedResources" />
  </ContentPage.Resources>
  
  <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
    <Entry Text="{Binding Name, Mode=TwoWay}" WidthRequest="250">
      <Entry.Behaviors>
        <behaviors:FieldEmptyValidatorBehavior x:Name="StringEmptyValidator" />
        <behaviors:FieldLengthValidatorBehavior MaxLength="255" />
      </Entry.Behaviors>
    </Entry>
    <Label Style="{Binding Source={x:Reference StringEmptyValidator}, 
                        Path=IsValid, 
                        Converter={StaticResource boolToStringEmpty}}" />
  </StackLayout>

La Entry ha una collection chiamata Behaviors, all'interno della quale metto tutte le istanze dei behavior che voglio usare. Notate come il primo abbia anche un nome, grazie al quale la Label sottostante può fare binding per conoscere lo stato della proprietà IsValid e per applicare il relativo stile a seconda del suo valore.

Alla fine di tutto, il risultato è questo:



La Label rossa sparirà quando digiteremo del testo all'interno della Entry e se tenteremo di scrivere più di 255 caratteri, la stringa verrà tagliata.

Gli errori vengono aggiunti e rimossi al Dictionary definito la volta scorsa, che controlleremo prima di fare altro anche perché, come detto, questa è più una forma di presentazione nella UI di un problema, più che una vera validazione dei dati. Ma tant'è.

Alessandro

Print | posted on giovedì 22 settembre 2016 22:07 | Filed Under [ Xamarin ]

Powered by:
Powered By Subtext Powered By ASP.NET