WPF TextBox模仿PasswordBox的密码显示功能

WPF TextBox模仿PasswordBox的密码显示功能WPFTextBox显示密码,模仿PasswordBox的功能

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

WPF TextBox模仿PasswordBox的密码显示功能

这并不是多此一举,因为WPF的PasswordBox不支持继承,所以想扩展PasswordBox的属性就没法实现,所以有了本文内容,当然这个思路也可以扩展到其他语言。

已经更新了升级版,链接如下升级版链接
https://blog.csdn.net/qq_41908152/article/details/122067744

一、添加属性 Password,用于存储密码

public string Password { 
    get; set; } = string.Empty;

二、添加属性 PasswordChar,用于设置显示为密码的字符,默认为 ‘●’

public char PasswordChar { 
    get; set; } = '●';

三、重写TextBox的TextChanged事件事件,代码以及内部逻辑如下(用户有可能往密码框里粘贴密码,以下代码已全部考虑到了此操作)

//重写文本框内容改变事件
        protected override void OnTextChanged(TextChangedEventArgs e)
        { 
   
            base.OnTextChanged(e);
            //已键入的文本长度 Text 为 TextBox 的属性(获取或设置文本框的文本内容)
            int textLength = Text.Length;
            //已保存的密码长度
            int psdLength = Password.Length;
            //起始修改位置
            int startIndex = -1;
            for (int i = 0; i < textLength; i++)
            { 
   
                if (Text[i] != PasswordChar)
                { 
   
                    startIndex = i;
                    break;
                }
            }
            //未作任何修改
            if (startIndex == -1 && textLength == psdLength) return;
            //结束修改位置
            int stopIndex = -1;
            for (int i = textLength - 1; i >= 0; i--)
            { 
   
                if (Text[i] != PasswordChar)
                { 
   
                    stopIndex = i;
                    break;
                }
            }
            //添加或修改了一个或连续的多个值
            if (startIndex != -1)
            { 
   
                //累计修改长度
                int alterLength = stopIndex - startIndex + 1;
                //长度没变化,单纯的修改了一个或连续的多个值
                if (textLength == psdLength)
                { 
   
                    Password = Password.Substring(0, startIndex) + Text.Substring(startIndex, alterLength) + Password.Substring(stopIndex + 1);
                }
                //新增了内容
                else
                { 
   
                    //新增且修改了原来内容
                    if (alterLength > textLength - psdLength)
                    { 
   
                        //计算未修改密码个数 textLength - alterLength
                        //计算已修改密码个数 = 原密码长度 - 未修改密码个数 psdLength - (textLength - alterLength)
                        //原密码该保留的后半部分的索引 = 已修改密码个数 + 起始修改位置
                        Password = Password.Substring(0, startIndex) + Text.Substring(startIndex, alterLength) + Password.Substring(psdLength - (textLength - alterLength) + startIndex);
                    }
                    //单纯的新增了一个或多个连续的值
                    else
                    { 
   
                        Password = Password.Substring(0, startIndex) + Text.Substring(startIndex, alterLength) + Password.Substring(startIndex);
                    }

                }
            }
            //删除了一个或连续的多个值
            else
            { 
   
                //已删除的数据长度 SelectionStart 为 TextBox 的属性(获取或设置当前所选内容的起始位置的字符索引)
                int length = psdLength - textLength;
                if (SelectionStart < textLength)
                { 
   
                    //改变了中间的数据
                    Password = Password.Substring(0, SelectionStart) + Password.Substring(SelectionStart + length);
                }
                else
                { 
   
                    //删除了结尾的数据
                    Password = Password.Substring(0, SelectionStart);
                }
            }
            //记住光标位置(设置完Text后会丢失,所以现在要记住)
            int selectionStart = SelectionStart;
            //设置显示密码
            Text = new string(PasswordChar, textLength);
            //设置光标位置
            SelectionStart = selectionStart;
        }

怕有些初学者迷茫,把完整的类也贴出来吧(这是创建了一个“自定义控件”),虽然没啥东西(包含上述代码)

using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SuperControl
{ 
   
    public class SuperPasswordBox : TextBox
    { 
   
        static SuperPasswordBox()
        { 
   
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SuperPasswordBox), new FrameworkPropertyMetadata(typeof(TextBox)));
        }

        /// <summary>
        /// 密码
        /// </summary>
        public string Password { 
    get; set; } = string.Empty;

        /// <summary>
        /// 显示为密码的字符
        /// </summary>
        public char PasswordChar { 
    get; set; } = '●';

        //重写文本框内容改变事件
        protected override void OnTextChanged(TextChangedEventArgs e)
        { 
   
            base.OnTextChanged(e);
            //已键入的文本长度
            int textLength = Text.Length;
            //已保存的密码长度
            int psdLength = Password.Length;
            //起始修改位置
            int startIndex = -1;
            for (int i = 0; i < textLength; i++)
            { 
   
                if (Text[i] != PasswordChar)
                { 
   
                    startIndex = i;
                    break;
                }
            }
            //未作任何修改
            if (startIndex == -1 && textLength == psdLength) return;
            //结束修改位置
            int stopIndex = -1;
            for (int i = textLength - 1; i >= 0; i--)
            { 
   
                if (Text[i] != PasswordChar)
                { 
   
                    stopIndex = i;
                    break;
                }
            }
            //添加或修改了一个或连续的多个值
            if (startIndex != -1)
            { 
   
                //累计修改长度
                int alterLength = stopIndex - startIndex + 1;
                //长度没变化,单纯的修改了一个或连续的多个值
                if (textLength == psdLength)
                { 
   
                    Password = Password.Substring(0, startIndex) + Text.Substring(startIndex, alterLength) + Password.Substring(stopIndex + 1);
                }
                //新增了内容
                else
                { 
   
                    //新增且修改了原来内容
                    if (alterLength > textLength - psdLength)
                    { 
   
                        //计算未修改密码个数 textLength - alterLength
                        //计算已修改密码个数 = 原密码长度 - 未修改密码个数 psdLength - (textLength - alterLength)
                        //原密码该保留的后半部分的索引 = 已修改密码个数 + 起始修改位置
                        Password = Password.Substring(0, startIndex) + Text.Substring(startIndex, alterLength) + Password.Substring(psdLength - (textLength - alterLength) + startIndex);
                    }
                    //单纯的新增了一个或多个连续的值
                    else
                    { 
   
                        Password = Password.Substring(0, startIndex) + Text.Substring(startIndex, alterLength) + Password.Substring(startIndex);
                    }

                }
            }
            //删除了一个或连续的多个值
            else
            { 
   
                //已删除的数据长度
                int length = psdLength - textLength;
                if (SelectionStart < textLength)
                { 
   
                    //改变了中间的数据
                    Password = Password.Substring(0, SelectionStart) + Password.Substring(SelectionStart + length);
                }
                else
                { 
   
                    //删除了结尾的数据
                    Password = Password.Substring(0, SelectionStart);
                }
            }
            //记住光标位置(设置完Text后会丢失,所以现在要记住)
            int selectionStart = SelectionStart;
            //设置显示密码
            Text = new string(PasswordChar, textLength);
            //设置光标位置
            SelectionStart = selectionStart;
        }
    }
}

有问题欢迎留言,如果觉得有用请点个”赞”,谢谢!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/161476.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java integer范围值的大小_java求数组最小值

    java integer范围值的大小_java求数组最小值java中Integer是有最大值和最小值的最大值为Integer.MAX_VALUE=2147483647最小值为Integer.MIN_VALUE=-2147483648注意:两个值并没有互为相反数有Integer.MAX_VALUE+1=Integer.MIN_VALUE同理Integer.MIN_VALUE-1=Integer.MAX_VALUE…

    2025年10月3日
    4
  • hisi3516dv300学习笔记——编译hisi3516dv300的SDK

    hisi3516dv300学习笔记——编译hisi3516dv300的SDK先下载linux内核源码包,下载地址:https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/(1)编译整个osdrv目录:注意:默认不发布内核源码包,只发布补丁文件。内核源码包需自行从开源社区上下载。从linux开源社区下载v4.9.37版本的内核:1)进入网站:www.kernel.org2)选择HTTP协议资源的https://www.kernel.org/pub/选项,进入子页面3)选择linux/菜单项,进入子页面4)选择ker

    2022年9月23日
    2
  • SpringMVC 执行流程

    SpringMVC 执行流程springMVC(javaweb开发框架)1、MVC三层架构:模型(service、dao)、视图(JSP等)、控制器(Controller)什么是mvc?*MVC是模型、视图、控制器的简写,是一种软件设计规范*是将业务逻辑、数据、显示分离的方法来组织代码*MVC主要的作用就是降低了控制器(Controller)和视图(View)之间的双向耦合度*MVC不是一种设计模式、MVC是一种架构模式。当然不同的MVC存在着差异Model(数据模型):提供要展示的数据。因此包含数据和

    2022年6月28日
    25
  • 我们做出了一个艰难的决定

    我们做出了一个艰难的决定经过半年多的考虑和准备,前天晚上,我们做出了一个艰难的决定:让大儿子在家读书。我厌倦了孩子题海战术,买的课外书根本没有时间读,而他的身心健康变得越来越糟糕了。我知道有很多的理由可以让孩子继续读书,譬如

    2022年7月3日
    21
  • ldd命令 ubuntu_ldd命令

    ldd命令 ubuntu_ldd命令1.在制作自己的发行版时经常需要判断某条命令需要哪些共享库文件的支持,以确保指定的命令在独立的系统内可以可靠的运行;在Linux环境下通过ldd命令即可实现,在终端下执行:ldd/bin/ls//ldd命令通常使用”-v”或”–verbose”选项来显示所依赖的动态连接库的尽可能的详细信息。即可得到/bin/ls命令的相关共享库文件列表:libtermcap.so.2=>/lib/…

    2022年6月13日
    50
  • mysql 提示表不存在的解决方法error: 1146: Table doesn‘t exist

    mysql 提示表不存在的解决方法error: 1146: Table doesn‘t exist直接拷贝数据库导致提示表不存在的解决方法电脑重装系统后把原来的mysqldata复制进去后大部分表是可以访问的,但是有几个表提示表不存在:error:1146:Table’a_content’doesn’texist这种情况就是要把原来mysql安装目录data里的ibdata1也要拷贝过去INNODB是MYSQL数据库一种流行的数据库引擎,支持事务(行级),在企业级应…

    2022年6月14日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号