2017-03-06 2 views
2

J'utilise Xamarin.Forms et je souhaite avoir un clavier numérique uniquement pour que mes utilisateurs puissent se connecter avec un code PIN.Xamarin.Forms.UWP Clavier numérique uniquement sur un clavier logiciel

Je peux utiliser Xamarin.Forms.Entry.Keyboard = Keyboard.Numeric pour forcer un clavier numérique, et cela fonctionne pour les téléphones iOS, Android et UWP. Toutefois, lorsqu'un utilisateur exécute la même application sur une tablette UWP, comme Microsoft Surface, il affiche le clavier complet, qui comprend des caractères et des nombres.

Je souhaite qu'un clavier numérique soit la seule option d'entrée pour rendre la validation des données plus simple et plus sûre.

Je sais que je peux facilement effectuer la validation car le texte change pour assurer que seuls les nombres sont présents, mais est-il possible d'afficher uniquement le clavier numérique sur le clavier logiciel pour un Xamarin.Forms.Entry sur la plate-forme UWP?

Répondre

2

J'ai donc pensé à celui-ci moi-même et je voulais poster la réponse pour les futurs développeurs. Ce cas d'utilisation provient de l'affichage du clavier logiciel sur les tablettes UWP car Xamarin.Forms.Entry utilise le Windows.UI.Xaml.Controls.TextBox. Vous pouvez changer le InputScope du TextBox pour changer le clavier dans UWP comme indiqué dans le documentation.

Bien sûr, j'ai fait l'erreur commune de ne pas lire la documentation entièrement, mais plutôt de sauter directement à ce que les claviers sont disponibles. Dans les documents il y a une ligne importante au début:

Important La propriété InputScope sur PasswordBox ne supporte que les Password et NumericPin values. Toute autre valeur est ignorée.

Oh snap! Nous utilisons un TextBox lorsque nous voulons vraiment utiliser un PasswordBox pour UWP. Cela peut facilement être réalisé avec une entrée CustomRenderer et personnalisé comme ci-dessous:

Entrée personnalisée:

public class MyCustomPasswordNumericEntry: Xamarin.Forms.Entry 
{ 
} 

personnalisés Renderer:

public class PasswordBoxRenderer : ViewRenderer<Xamarin.Forms.Entry, Windows.UI.Xaml.Controls.PasswordBox> 
{ 
    Windows.UI.Xaml.Controls.PasswordBox passwordBox = new Windows.UI.Xaml.Controls.PasswordBox(); 
    Entry formsEntry; 
    public PasswordBoxRenderer() 
    { 
     var scope = new InputScope(); 
     var name = new InputScopeName(); 

     name.NameValue = InputScopeNameValue.NumericPin; 
     scope.Names.Add(name); 

     passwordBox.InputScope = scope; 
    } 

    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e) 
    { 
     base.OnElementChanged(e); 

     if (Control == null) 
     { 
      SetNativeControl(passwordBox); 
     } 

     if(e.NewElement != null) 
     { 
      formsEntry = e.NewElement as Entry; 

      passwordBox.PasswordChanged += TextChanged; 
      passwordBox.FocusEngaged += PasswordBox_FocusEngaged; 
      passwordBox.FocusDisengaged += PasswordBox_FocusDisengaged; 
     } 

     if(e.OldElement != null) 
     { 
      passwordBox.PasswordChanged -= TextChanged; 
     } 
    } 

    private void PasswordBox_FocusDisengaged(Windows.UI.Xaml.Controls.Control sender, Windows.UI.Xaml.Controls.FocusDisengagedEventArgs args) 
    { 
     formsEntry.Unfocus(); 
    } 

    private void PasswordBox_FocusEngaged(Windows.UI.Xaml.Controls.Control sender, Windows.UI.Xaml.Controls.FocusEngagedEventArgs args) 
    { 
     formsEntry.Focus(); 
    } 

    private void TextChanged(object sender, Windows.UI.Xaml.RoutedEventArgs e) 
    { 
     formsEntry.Text = passwordBox.Password; 
    } 
} 

Et enfin assurez-vous que nous enregistrons juste la PersonnaliséRenderer:

[assembly: Xamarin.Forms.Platform.UWP.ExportRenderer(typeof(MyCustomPasswordNumericEntry), typeof(PasswordBox.UWP.PasswordBoxRenderer))] 

Maintenant, notre MyCustomPasswordNumericEntry utilisera un Xamarin.Forms.Entry sur toutes les plateformes, mais utilisera un Windows.UI.Xaml.Controls.PasswordBox sur UWP. J'ai également transmis les événements de base sur le Xamarin.Forms.Entry pour que tout fonctionne, mais vous devez également avoir la méthode OnElementPropertyChanged() mettre à jour le PasswordBox s'il y a des modifications provenant de Validation sur la propriété Xamarin.Forms.Entry.TextChanged.