在UWP PasswordBox中过滤字符的正确方法是什么?

时间:2019-07-23 17:39:33

标签: c# xaml uwp passwordbox

我有一个UWP应用程序,该应用程序使用PasswordBox控件输入模糊的文本。密码的有效字符因实例而异,并且在运行时由ViewModel层知道。我希望能够在用户键入无效字符时对其进行过滤。正确的方法是什么?

我们对常规TextBox控件有类似的要求。我们已经能够使用TextChanging事件和SelectionStart属性来重置光标位置,从而对文本框执行这种过滤。但是,PasswordBox没有任何一个。

密码框的XAML如下

    <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}" />

然后我们通过检查输入的有效性来对Password.set进行响应,如果无效,则重置为先前的值

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

对SetCurrentValue()的调用只是将输入的密码存储在我们的模型层中,因此不会对本讨论产生影响。调用_passwordControl.SetPassword将更新ThePasswordBox上的“密码”字段:

    public void SetPassword(string password)
    {
        ThePasswordBox.Password = password;
    }

HandlePasswordChange()强制其他UI元素重新评估,包括在控件无效时禁用的OK按钮。对于这个问题,它的实现不重要。

此方法的问题在于,当我们重置PasswordBox的内容(对SetPassword的调用,该调用将设置PasswordBox.Password属性)时,光标跳到第一个位置。因此,对于数字密码,键入“ 12a4”将产生“ 412”。

我们在这里有什么选择?

2 个答案:

答案 0 :(得分:1)

  

在UWP PasswordBox中过滤字符的正确方法是什么?

从您的代码中,您无需在SetPassword中调用Password.set方法,它将使光标回到起始位置。更好的方法是在双向模式下绑定Password。并检查密码是否可用。如果Password包含不允许的字符,请用InputInjector调用 BackSpace

public string PassWord
{

    get { return _passWord; }
    set
    {
        if(value != null && IsPasswordContentAcceptable(value))
        {
            _passWord = value;
            OnPropertyChanged();
        }
        else
        {
            InputInjector inputInjector = InputInjector.TryCreate();
            var info = new InjectedInputKeyboardInfo();
            info.VirtualKey = (ushort)(VirtualKey.Back);
            inputInjector.InjectKeyboardInput(new[] { info });               
        }

    }
}

Xaml

<PasswordBox
    x:Name="ThePassWordBox"
    MaxLength="20"
    Password="{x:Bind PassWord, Mode=TwoWay}"      
    PlaceholderText="Input your Password"
    />

有关在UWP应用中注入输入的信息,请参阅此blog

答案 1 :(得分:0)

或者,您可以在收到输入时取消输入。 在此示例中,密码框中允许使用除“ A”以外的所有字符

Xaml

    <PasswordBox Name="pwBox"></PasswordBox>

代码

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        CoreWindow cw = CoreWindow.GetForCurrentThread();
        CoreDispatcher cd = cw.Dispatcher;

        cd.AcceleratorKeyActivated += Cd_AcceleratorKeyActivated;
        this.InitializeComponent();
    }

    private void Cd_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
    {
        if (this.pwBox.FocusState != FocusState.Unfocused)
        {
            if(args.VirtualKey == Windows.System.VirtualKey.A)
            {
                args.Handled = true;
            }
        }
    }
}