So I figured this one out myself and wanted to post the answer for future developers. This use case comes from having the soft keyboard displayed on UWP tablets because Xamarin.Forms.Entry
utilizes the Windows.UI.Xaml.Controls.TextBox
. You can change the InputScope
of the TextBox
to change the keyboard in UWP as shown in the documentation.
Of course I made the common mistake of not reading the documentation entirely, but rather jumping straight to what keyboards are available. In the docs there is an important line in the beginning:
Important The InputScope
property on PasswordBox
supports only the Password
and NumericPin values
. Any other value is ignored.
Oh snap! We're using a TextBox
when we really want to use a PasswordBox
for UWP. This can easily be achieved with a CustomRenderer and custom entry like below:
Custom Entry:
public class MyCustomPasswordNumericEntry: Xamarin.Forms.Entry
{
}
Custom 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;
}
}
And lastly make sure we just register the CustomRenderer:
[assembly: Xamarin.Forms.Platform.UWP.ExportRenderer(typeof(MyCustomPasswordNumericEntry), typeof(PasswordBox.UWP.PasswordBoxRenderer))]
Now our MyCustomPasswordNumericEntry
will use a Xamarin.Forms.Entry
on all platforms, but will use a Windows.UI.Xaml.Controls.PasswordBox
on UWP. I also forwarded the basic events on the Xamarin.Forms.Entry
to make everything work, but you would also need to have the OnElementPropertyChanged()
method update the PasswordBox
if there are changes coming from Validation on the Xamarin.Forms.Entry.TextChanged property.