2017-03-06 77 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