I have a UWP application which uses a PasswordBox control for obscured text entry. The valid characters for the password varies by instance, and is known by the ViewModel layer at runtime. I want to be able to filter invalid characters as the user types them. What is the proper way to do that?
We have similar requirements for regular TextBox controls. We have been able to perform this kind of filtering for text boxes using the TextChanging event and the SelectionStart property for resetting the cursor position. But the PasswordBox does not have either of these.
The XAML for the password box looks like this
<PasswordBox
x:Name="ThePasswordBox"
Grid.Row="1"
MaxLength="{Binding MaxPasswordLength, Mode=OneTime}"
IsEnabled="{Binding IsPasscodeEnabled, Mode=OneWay}"
Password="{Binding Password, FallbackValue=1234, Mode=TwoWay}"
PlaceholderText= "{Binding PlaceholderText, Mode=OneWay}" />
We then respond to the Password.set by checking the validity of the input, and if invalid, resetting to the prior value
set
{
if (_password != value && value != null)
{
// verify that the new password would be valid; if not, roll back
if (!IsPasswordContentAcceptable(value))
{
_passcodeControl.SetPassword(_password);
return;
}
_password = value;
// push the new password to the data binding
_passcodeDataBinding.SetCurrentValue(_password);
// update the UI
HandlePasswordChange();
OnPropertyChanged("Password");
}
}
The call to SetCurrentValue() simply stores the entered password into our Model layer and should not be of consequence to this discussion. The call to _passwordControl.SetPassword updates the Password field on ThePasswordBox:
public void SetPassword(string password)
{
ThePasswordBox.Password = password;
}
HandlePasswordChange() forces other UI elements to re-evaluate, including an OK button that is disabling when the control is invalid. It's implementation should not be important to this question.
The problem with this approach is that when we reset the contents of the PasswordBox (the call to SetPassword, which sets PasswordBox.Password property) the cursor jumps to the first position. So for a numeric password, typing "12a4" would yield "412".
What are our options here?
_passcodeControl.SetPassword
and_passcodeDataBinding.SetCurrentValue
method. please share minimal reproducible example for us. – Nico Zhu - MSFT