WPF应用程序的手机/平板电脑样式密码框

时间:2016-09-27 19:04:28

标签: c# wpf passwords wpf-controls

有没有办法让WPF应用程序中的PasswordBox像大多数手机或平板电脑应用程序中使用的那样工作。也就是说,让它显示在短文中输入的最后一个字符。

1 个答案:

答案 0 :(得分:2)

没有办法内置这样做,因为它打破了安全准则。有关不建议这样做的更多信息,请参阅此帖子: How to bind to a PasswordBox in MVVM

这是接受的答案:

  

人们的眼睑内侧应有以下安全指南:   切勿将纯文本密码保存在内存中。

     

WPF / Silverlight PasswordBox没有为Password属性公开DP的原因与安全性有关。   如果WPF / Silverlight要保留DP for Password,则需要框架将密码本身保持在内存中未加密。这被认为是一个非常麻烦的安全攻击媒介。 PasswordBox使用加密内存(各种类型),访问密码的唯一方法是通过CLR属性。

如果你仍然希望实现这一点,我可以使用TextBox控件来实现。

<强> XAML:

 <TextBox Name="tbPassword"/>

<强>代码隐藏:

  string actualPassword = "";
  string displayedPassword = "";
  DispatcherTimer dispatcherTimer = new DispatcherTimer();

  public MainWindow()
  {
     InitializeComponent();
     tbPassword.PreviewKeyDown += tbPassword_PreviewKeyDown;
     tbPassword.PreviewTextInput += tbPassword_PreviewTextInput;

     dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
     dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
  }

  private void tbPassword_PreviewKeyDown(object sender, KeyEventArgs e)
  {
     if (e.Key == Key.Back)
     {
        if (actualPassword.Length > 0)
        {
           actualPassword = actualPassword.Substring(0, actualPassword.Length - 1);
           if (actualPassword.Length > 0)
           {
              ShowLastCharacter();
              tbPassword.CaretIndex = displayedPassword.Length;
           }
        }
     }
  }

  private void tbPassword_PreviewTextInput(object sender, TextCompositionEventArgs e)
  {
     actualPassword += e.Text;
     e.Handled = true;
     ShowLastCharacter();
     tbPassword.CaretIndex = displayedPassword.Length;
  }


  private void ShowLastCharacter()
  {
     var lastChar = actualPassword.Substring(actualPassword.Length - 1);
     displayedPassword = "";
     for (int i = 0; i < actualPassword.Length - 1; i++)
        displayedPassword += "•";
     displayedPassword += lastChar;
     tbPassword.Text = displayedPassword;

     if (dispatcherTimer.IsEnabled)
        dispatcherTimer.Stop();

     dispatcherTimer.Start();
  }

  private void dispatcherTimer_Tick(object sender, EventArgs e)
  {
     displayedPassword = "";
     for (int i = 0; i < actualPassword.Length; i++)
        displayedPassword += "•";

     tbPassword.Text = displayedPassword;
     tbPassword.CaretIndex = displayedPassword.Length;
  }