WPF PasswordBox控件使用
一、PasswordBox的SecurePassword属性
正常的String类型值,在脱离开作用域之后,其值在内存中并不会被立即销毁,这时如果有人恶意扫描你的内存,程序中所保存的机密信息就会暴露;于是就有了System.Security.SecureString,SecureString表示一个应保密的文本,它在初始化时就已被加密,并且脱离作用域后会被立即销毁。PasswordBox提供了SecurePassword属性,该属性提供的是一个SecureString类型,SecureString类型转换为string类型如下所示:
IntPtr p = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(this.LoginPasswordBox.SecurePassword);
string password = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p);
二、PasswordBox的密码明文展示样式实现
由于Password属性不是依赖属性,所以要实现密码的明文展示需要通过附加属性来实现,具体代码如下所示:

public class PasswordBoxAttached
{
public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordBoxAttached), new PropertyMetadata("", PasswordPropertyChangedCallback));
[AttachedPropertyBrowsableForType(typeof(System.Windows.Controls.PasswordBox))]
public static string GetPassword(DependencyObject obj)
{
return (string)obj.GetValue(PasswordProperty);
}
public static void SetPassword(DependencyObject obj, string value)
{
obj.SetValue(PasswordProperty, value);
}
private static void PasswordPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is System.Windows.Controls.PasswordBox pb)
{
pb.Password = e.NewValue.ToString();
pb.GetType().GetMethod("Select", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(pb, new object[] { pb.Password.Length, 0 });
}
}
}
private void LoginPasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e)
{
if (sender is System.Windows.Controls.PasswordBox pb)
{
PasswordBoxAttached.SetPassword(pb, pb.Password);
}
}