using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Security; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; namespace Wpf自定义密码框 { public class CustomPassword:TextBox { public CustomPassword() { InputMethod.SetIsInputMethodEnabled(this,false); Loaded += Tbx_Loaded; PreviewTextInput += Tbx_PreviewTextInput; CommandManager.AddPreviewExecutedHandler(this, PreviewExecutedHandler); PreviewKeyDown += OnPreviewKeyDown; _changePasswordCharTimer = new DispatcherTimer(); _changePasswordCharTimer.Interval = TimeSpan.FromSeconds(1); _changePasswordCharTimer.Tick += Tm_Tick; } private readonly DispatcherTimer _changePasswordCharTimer; public string SecureStringToString(SecureString value) { var valuePtr = IntPtr.Zero; try { valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value); return Marshal.PtrToStringUni(valuePtr); } finally { Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); } } private void AddChar(char c) { //移除选中项 var start = SelectionStart; var length = SelectionLength; if (length > 0) { Text = Text.Remove(start, length); for (var i = 0; i < length; i++) { Password.RemoveAt(start); } Select(start, 0); } //修改文本为***9类型,只保留最后一位 var part1 = ""; var part2 = c.ToString(); var part3 = new string('*', Text.Length - start); if (start > 0) { part1 = new string('*', start); } Console.WriteLine("-------------,start:" + start + ",txtLength:" + Text.Length + " part1: " + part1 + ",part2:" + part2 + ",part3:" + part3); { //向后添加 Text = part1 + part2 + part3; Password.InsertAt(start, c); Select(start + 1, 0); FocusManager.SetFocusedElement(Window. GetWindow(this), this); } //增加当前添加项 _changePasswordCharTimer.Stop(); _changePasswordCharTimer.Start(); } private void OnPreviewKeyDown(object sender, KeyEventArgs keyEventArgs) { var pressedKey = keyEventArgs.Key == Key.System ? keyEventArgs.SystemKey : keyEventArgs.Key; switch (pressedKey) { case Key.Space: AddChar(' '); keyEventArgs.Handled = true; break; case Key.Back: case Key.Delete: var start = SelectionStart; var length = SelectionLength; if (length > 0) { Text = Text.Remove(start, length); for (var i = 0; i < length; i++) { Password.RemoveAt(start); } Select(start, 0); } else if (pressedKey == Key.Delete && start < Text.Length) { Text = Text.Remove(start, 1); Password.RemoveAt(start); Select(start, 0); } else if (pressedKey == Key.Back && start > 0) { if (start <= Text.Length) { start = start - 1; } Text = Text.Remove(start, 1); Password.RemoveAt(start); Select(start, 0); } keyEventArgs.Handled = true; break; } } /// <summary> /// 禁用复制粘贴快捷键 /// </summary> /// <param name="sender"></param> /// <param name="executedRoutedEventArgs"></param> private static void PreviewExecutedHandler(object sender, ExecutedRoutedEventArgs executedRoutedEventArgs) { if (executedRoutedEventArgs.Command == ApplicationCommands.Copy || executedRoutedEventArgs.Command == ApplicationCommands.Cut || executedRoutedEventArgs.Command == ApplicationCommands.Paste) { executedRoutedEventArgs.Handled = true; } } private void Tbx_Loaded(object sender, RoutedEventArgs e) { Password = new SecureString(); foreach (var c in Text) { Password.AppendChar(c); } Text = new string('*', Text.Length); } private void Tbx_PreviewTextInput(object sender, TextCompositionEventArgs e) { foreach (var c in e.Text) { AddChar(c); } e.Handled = true; } private void Tm_Tick(object sender, EventArgs e) { _changePasswordCharTimer.Stop(); var start = SelectionStart; if (SelectionLength > 0) { start = start + SelectionLength; } Text = new string('*', Text.Length); Console.WriteLine("====length:" + Text.Length + ",start:" + start); Console.WriteLine("密码是: " + SecureStringToString(Password)); Select(start, 0); FocusManager.SetFocusedElement(Window. GetWindow(this), this); } public SecureString Password { get; set; } } }
效果图: