Astuce Xamarin Forms : personnaliser complètement le Picker
Le Picker de Xamarin Forms (XF) permet de proposer à l'utilisateur de choisir un élément parmi une liste de valeurs. Fidèle à la philosophie d'XF, son rendu sera celui de la plateforme d'execution. Seulement, lorsque l'on souhaite personnaliser son affichage, on se retrouve vite limité.
Dans cet article, nous verrons une astuce pour avoir n'importe quel affichage du "mode fermé" : comment personnaliser le "bouton" qui ouvre le contenu. Il ne s'agit pas de centaines de lignes de code mais d'une petite astuce qui peut vous faire gagner beaucoup de temps.
Pour rappel, le design sur les différentes plateformes mobile est le suivant (tiré de la documentation) :
L'astuce
J'ai passé beaucoup de temps à chercher des extraits de code pour personnaliser comme je le souhaitais le Picker avec des méthodes spécifiques à chaque plateforme, des renderers, etc. Aucune ne me convenait car très complexes pour un besoin relativement simple. J'en suis donc arrivé à trouver une façon de faire beaucoup plus rapide même si un peu sale... L'objectif est d'avoir ce type de rendu "uniforme" avec le reste de l'application :
Il s'agit de tricher un peu en ajoutant dans notre XAML un Picker avec une taille de 0 pixel de haut.
<Picker HeightRequest="0" ItemDisplayBinding="{Binding Label}" x:Name="PickerAutomaticStop" ItemsSource="{Binding AutomaticStopValues}" SelectedIndex="3" SelectedIndexChanged="Handle_SelectedIndexChanged" />
Pour proposer à l'utilisateur les valeurs à choisir, il suffira de donner le Focus à notre contrôle Picker. On le fera par exemple lors du click sur un élément :
void Handle_StopInClicked(object sender, EventArgs e) { PickerAutomaticStop.Focus(); }
Vous pouvez ainsi placer n'importe quel élément dans votre XAML pour représenter le Picker en question et déclencher son ouverture au besoin. Dans mon cas, j'ai créé un layout complètement personnalisé :
<Frame HorizontalOptions="Fill" Padding="8" HasShadow="false" CornerRadius="5" BackgroundColor="#EDEDED"> <Frame.GestureRecognizers> <TapGestureRecognizer Tapped="Handle_StopInClicked" /> </Frame.GestureRecognizers> <StackLayout HorizontalOptions="Center" Orientation="Horizontal"> <controls:FALabel FontSize="16" Text="" TextColor="{StaticResource MainColor}" VerticalTextAlignment="Center" /> <Label Margin="0" FontSize="16" TextColor="{StaticResource MainColor}" VerticalTextAlignment="Center" Text="{Binding AudioService.DisplayableAutomaticStop}" /> </StackLayout> </Frame>
Une fois dans l'application, cela devient complètement transparent pour vos utilisateurs :
Commentaires