WPF自定义密码框 custom password,iOS模式,有密码最后一位输入提示

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

效果图:

原文地址:https://www.cnblogs.com/congqiandehoulai/p/14547959.html