Phone/Tablet WPF 应用程序的样式密码框
Phone/Tablet Style password box for WPF application
有什么方法可以使 WPF 应用程序中的 PasswordBox
像大多数 phone 或平板电脑应用程序中使用的那样工作。也就是说,让它短时间显示明文输入的最后一个字符。
没有内置方法可以执行此操作,因为它违反了安全准则。请参阅此 post 以了解有关不推荐这样做的原因的更多信息:
How to bind to a PasswordBox in MVVM
这是被接受的答案:
People should have the following security guideline tattooed on the inside of their eyelids:
Never keep plain text passwords in memory.
The reason the WPF/Silverlight PasswordBox doesn't expose a DP for the Password property is security related.
If WPF/Silverlight were to keep a DP for Password it would require the framework to keep the password itself unencrypted in memory. Which is considered quite a troublesome security attack vector. The PasswordBox uses encrypted memory (of sorts) and the only way to access the password is through the CLR property.
如果您仍想实现此目的,我可以使用 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;
}
有什么方法可以使 WPF 应用程序中的 PasswordBox
像大多数 phone 或平板电脑应用程序中使用的那样工作。也就是说,让它短时间显示明文输入的最后一个字符。
没有内置方法可以执行此操作,因为它违反了安全准则。请参阅此 post 以了解有关不推荐这样做的原因的更多信息: How to bind to a PasswordBox in MVVM
这是被接受的答案:
People should have the following security guideline tattooed on the inside of their eyelids: Never keep plain text passwords in memory.
The reason the WPF/Silverlight PasswordBox doesn't expose a DP for the Password property is security related. If WPF/Silverlight were to keep a DP for Password it would require the framework to keep the password itself unencrypted in memory. Which is considered quite a troublesome security attack vector. The PasswordBox uses encrypted memory (of sorts) and the only way to access the password is through the CLR property.
如果您仍想实现此目的,我可以使用 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;
}