2017-03-06 79 views
2

我使用Xamarin.Forms,并希望只有一个数字键盘,供我的用户使用PIN登录。Xamarin.Forms.UWP数字键盘只在软键盘上

我可以使用Xamarin.Forms.Entry.Keyboard = Keyboard.Numeric强制使用数字键盘,这适用于iOS,Android和UWP手机。但是,当用户在UWP平板电脑(如Microsoft Surface)上运行相同的应用程序时,它会显示完整键盘,其中包含字符和数字。

我想要一个数字键盘是唯一的输入选项,使数据验证更简单和安全。

我知道我可以很容易地进行验证作为文本更改,以确保只有数字存在,但有没有办法在UWP平台上的Xamarin.Forms.Entry的软键盘上只显示数字键盘?

回答

2

所以我想出了这个问题,并希望为未来的开发者发布答案。此用例来自UWP平板电脑上显示的软键盘,因为Xamarin.Forms.Entry使用了Windows.UI.Xaml.Controls.TextBox。您可以更改TextBoxInputScope以更改UWP中的键盘,如documentation中所示。

当然,我犯了一个普遍的错误,就是完全没有阅读文档,而是直接跳到可用的键盘上。在文档没有在一开始的重要防线:

重要InputScope财产上PasswordBox只支持PasswordNumericPin values。任何其他值都会被忽略。

哦,快点!当我们真的想为UWP使用PasswordBox时,我们正在使用TextBox

自定义项:

public class MyCustomPasswordNumericEntry: Xamarin.Forms.Entry 
{ 
} 

自定义呈现:

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; 
    } 
} 

而且最后要确保我们只注册这可以很容易地用CustomRenderer和自定义入口像下面实现CustomRenderer:

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

现在我们的MyCustomPasswordNumericEntry将在所有平台上使用Xamarin.Forms.Entry,但将在UWP上使用Windows.UI.Xaml.Controls.PasswordBox。我还转发了Xamarin.Forms.Entry上的基本事件以使所有工作都成功,但如果Xamarin.Forms.Entry.TextChanged属性中的验证发生更改,则还需要使用OnElementPropertyChanged()方法更新PasswordBox