WPF TextBox模仿PasswordBox的密码显示功能(二)(升级版)

WPF TextBox模仿PasswordBox的密码显示功能(二)(升级版)WPFTextBox显示密码,模仿PasswordBox功能

大家好,又见面了,我是你们的朋友全栈君。

WPF TextBox模仿PasswordBox的密码显示功能(二)(升级版)

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

一、新建自定义控件
在这里插入图片描述二、下面是完整的类(这是创建了一个“自定义控件”)

using System.Windows;
namespace SuperControl
{ 

/// <summary>
/// SuperPasswordBoxPro
/// </summary>
public class SuperPasswordBoxPro : TextBox
{ 

static SuperPasswordBoxPro()
{ 

DefaultStyleKeyProperty.OverrideMetadata(typeof(SuperPasswordBoxPro), new FrameworkPropertyMetadata(typeof(STextBox)));
//重写Text属性改变回调方法
TextProperty.OverrideMetadata(typeof(SuperPasswordBoxPro), new FrameworkPropertyMetadata(new PropertyChangedCallback(TextChangedCallback)));
}
//Text属性改变回调方法
private static void TextChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ 

SuperPasswordBoxPro instance = (SuperPasswordBoxPro)d;
//新的前端密码文本
string text = e.NewValue.ToString();
//已键入的文本长度
int textLength = text.Length;
//已保存的密码长度
int psdLength = instance.Password.Length;
//判断密码是否已修改
if (textLength == psdLength && text == new string(instance.PasswordChar, text.Length)) return;
//记住光标位置(设置完Text后会丢失,所以现在要记住)
int selectionStart = instance.SelectionStart;
//起始修改位置
int startIndex = -1;
for (int i = 0; i < textLength; i++)
{ 

if (text[i] != instance.PasswordChar)
{ 

startIndex = i;
break;
}
}
//结束修改位置
int stopIndex = -1;
for (int i = textLength - 1; i >= 0; i--)
{ 

if (text[i] != instance.PasswordChar)
{ 

stopIndex = i;
break;
}
}
//添加或修改了一个或连续的多个值
if (startIndex != -1)
{ 

//累计修改长度
int alterLength = stopIndex - startIndex + 1;
//长度没变化,单纯的修改了一个或连续的多个值
if (textLength == psdLength)
{ 

instance.Password = instance.Password.Substring(0, startIndex) + text.Substring(startIndex, alterLength) + instance.Password.Substring(stopIndex + 1);
}
//新增了内容
else
{ 

//新增且修改了原来内容
if (alterLength > textLength - psdLength)
{ 

//计算未修改密码个数 textLength - alterLength
//计算已修改密码个数 = 原密码长度 - 未修改密码个数 psdLength - (textLength - alterLength)
//原密码该保留的后半部分的索引 = 已修改密码个数 + 起始修改位置
instance.Password = instance.Password.Substring(0, startIndex) + text.Substring(startIndex, alterLength) + instance.Password.Substring(psdLength - (textLength - alterLength) + startIndex);
}
//单纯的新增了一个或多个连续的值
else
{ 

instance.Password = instance.Password.Substring(0, startIndex) + text.Substring(startIndex, alterLength) + instance.Password.Substring(startIndex);
}
}
}
//删除了一个或连续的多个值
else
{ 

//已删除的数据长度 SelectionStart 为 TextBox 的属性(获取或设置当前所选内容的起始位置的字符索引)
int length = psdLength - textLength;
if (instance.SelectionStart < textLength)
{ 

//改变了中间的数据
instance.Password = instance.Password.Substring(0, instance.SelectionStart) + instance.Password.Substring(instance.SelectionStart + length);
}
else
{ 

//删除了结尾的数据
instance.Password = instance.Password.Substring(0, instance.SelectionStart);
}
}
//设置光标位置
instance.SelectionStart = selectionStart;
}
/// <summary>
/// 密码
/// </summary>
public string Password
{ 

get { 
 return (string)GetValue(PasswordProperty); }
set { 
 SetValue(PasswordProperty, value); }
}
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.Register("Password", typeof(string), typeof(SuperPasswordBoxPro), new PropertyMetadata("", new PropertyChangedCallback(PasswordChangedCallback)));
//Password属性改变回调方法
private static void PasswordChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ 

SuperPasswordBoxPro instance = (SuperPasswordBoxPro)d;
instance.Text = new string(instance.PasswordChar, e.NewValue.ToString().Length);
}
/// <summary>
/// 密码显示字符
/// </summary>
public char PasswordChar
{ 

get { 
 return (char)GetValue(PasswordCharProperty); }
set { 
 SetValue(PasswordCharProperty, value); }
}
public static readonly DependencyProperty PasswordCharProperty =
DependencyProperty.Register("PasswordChar", typeof(char), typeof(SuperPasswordBoxPro), new PropertyMetadata('●'));
}
}

三、如何使用
1、将命名空间改成你自己项目的,也就是nampspace和你项目保持一致
2、xaml里直接<local:SuperPasswordBoxPro />即可
3、Password属性才是真实的密码,请不要用Text属性
4、MVVM用到数据绑定的时候直接绑定Password属性即可

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

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/161499.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 实现括号匹配算法(括号匹配的检验算法完整程序)

    实现括号匹配算法(顺序表)括号匹配问题假设一个算术表达式中包含圆括号、方括号和花括号三种类型的括号,编写一个函数,用来判别表达式中的括号是否正确配对,并设计一个测试主函数。**【算法思想】**在算术表达式中,右括号和左括号匹配的次序正好符合后到的括号要最先被匹配的“后进先出”堆栈操作特点,因此可以借助一个堆栈来进行判断。括号匹配共有以下4种情况:左、右括号配对次序不正确;右括号多于左…

  • Spring Cloud版本说明

    Spring Cloud版本说明SpringCloud是一个由众多独立子项目组成的大型综合项目,每个子项目有不同的发行节奏,都维护着自己的发布版本号。SpringCloud通过一个资源清单BOM(BillofMaterials)来管理每个版本的子项目清单。为避免与子项目的发布号混淆,所以没有采用版本号的方式,而是通过命名的方式。这些版本名称的命名方式采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序,比如…

  • pycharm 搜索快捷键_word替换文字快捷键

    pycharm 搜索快捷键_word替换文字快捷键PyCharm快捷键——搜索/替换快捷键搜索/替换快捷键序号快捷键作用1CTRL+F查找2F3查找下一个3SHIFT+F3查找上一个4CTRL+R替换5CTRL+SHIFT+F指定路径下查找6CTRL+SHIFT+R指定路径下替换

  • Android 带password输入界面的Dialog实现机制

    Android 带password输入界面的Dialog实现机制

  • 离线centos6下安装Ambari2.2.1和HDP2.4

    离线centos6下安装Ambari2.2.1和HDP2.4

  • kibana 模糊匹配_匿名语音匹配app

    kibana 模糊匹配_匿名语音匹配app一.前言现在大多数的公司都会使用ELK组合来对日志数据的收集、存储和提供查询服务。ElasticSearch+Logstash+Kibana。查询数据库,如果是MySQL,那么就需要使用MySQL的语法;同样的,在Kibana上查询数据,也需要使用Kibana的语法,而Kibana的查询语法叫做KibanaQueryLanguage,简称KQL。二.KQL简单介绍KQL(KibanaQueryLanguage),也就是在Kibana上面进行查询时使用的语法。Kibana中也可以使

发表回复

您的电子邮箱地址不会被公开。

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