WPF 带水印的密码输入框实现
原文:WPF 带水印的密码输入框实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BYH371256/article/details/83505584

本章讲述:带水印的密码输入框实现

主要功能:带水印效果,控件提示图标,控件文本清除图标;

新建一个WPF项目,然后添加“自定义控件(WPF)”,命名为:“ExTextBox”

资源字典XAML前台样式

<Style TargetType="{x:Type local:ExTextBox}"><Setter Property="VerticalAlignment" Value="Center"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="BorderThickness" Value="1"/><Setter Property="BorderBrush" Value="Gray"/><Setter Property="Cursor" Value="IBeam"/><Setter Property="Padding" Value="3,0,0,0"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:ExTextBox}"><Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding BorderCornerRadius}" SnapsToDevicePixels="True"><Grid x:Name="gdpassword"><Grid.ColumnDefinitions><ColumnDefinition Width="auto"/><ColumnDefinition Width="*"/><ColumnDefinition Width="auto"/></Grid.ColumnDefinitions><Image x:Name="TipImage" Source="{Binding TipImage, RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding ImageSize, RelativeSource={RelativeSource TemplatedParent}}" Margin="0,2,0,0"Width="{Binding ImageSize, RelativeSource={RelativeSource TemplatedParent}}"Visibility="{Binding TipImageHide,RelativeSource={RelativeSource TemplatedParent}}"/><Grid Grid.Column="1"><ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/><TextBlock x:Name="txtRemark" Text="{TemplateBinding WaterRemark}" Foreground="Gray" VerticalAlignment="Center"Margin="{TemplateBinding Padding}" Visibility="Collapsed"/></Grid><Image x:Name="OperateImage" Grid.Column="2" Source="{Binding OperateImage, RelativeSource={RelativeSource TemplatedParent}}" Height="{Binding ImageSize, RelativeSource={RelativeSource TemplatedParent}}" Margin="0,2,0,0"Width="{Binding ImageSize, RelativeSource={RelativeSource TemplatedParent}}" Cursor="Hand"Visibility="{Binding OperateHide,RelativeSource={RelativeSource TemplatedParent}}"/></Grid></Border><ControlTemplate.Triggers><Trigger Property="Text" Value=""><Setter Property="Visibility" Value="Visible" TargetName="txtRemark"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter>
</Style>

实现

public class ExTextBox : TextBox        //1.首先创建一个类,继承TextBox{//2.指定依赖属性的实例重写基类型的元数据static ExTextBox(){DefaultStyleKeyProperty.OverrideMetadata(typeof(ExTextBox), new FrameworkPropertyMetadata(typeof(ExTextBox)));}Image OperateImageE;Image TipImageE;public override void OnApplyTemplate(){base.OnApplyTemplate();var bord = VisualTreeHelper.GetChild(this, 0) as Border;Grid gr = bord.FindName("gdpassword") as Grid;TipImageE = gr.FindName("TipImage") as Image;OperateImageE = gr.FindName("OperateImage") as Image;//TipImageE.PreviewMouseLeftButtonUp +=TipImageE_PreviewMouseLeftButtonUp;OperateImageE.PreviewMouseLeftButtonUp +=OperateImageE_PreviewMouseLeftButtonUp;}private void OperateImageE_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e){this.Text = "";}//3.定义依赖属性 public static DependencyProperty WaterRemarkProperty =DependencyProperty.Register("WaterRemark", typeof(string), typeof(ExTextBox));/// <summary>/// 水印文字/// </summary>public string WaterRemark{get { return GetValue(WaterRemarkProperty).ToString(); }set { SetValue(WaterRemarkProperty, value); }}public static DependencyProperty BorderCornerRadiusProperty =DependencyProperty.Register("BorderCornerRadius", typeof(CornerRadius), typeof(ExTextBox));/// <summary>/// 边框角度/// </summary>public CornerRadius BorderCornerRadius{get { return (CornerRadius)GetValue(BorderCornerRadiusProperty); }set { SetValue(BorderCornerRadiusProperty, value); }}public static DependencyProperty IsPasswordBoxProperty =DependencyProperty.Register("IsPasswordBox", typeof(bool), typeof(ExTextBox), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsPasswordBoxChnage)));/// <summary>/// 是否为密码框/// </summary>public bool IsPasswordBox{get { return (bool)GetValue(IsPasswordBoxProperty); }set { SetValue(IsPasswordBoxProperty, value); }}public static DependencyProperty PasswordCharProperty =DependencyProperty.Register("PasswordChar", typeof(char), typeof(ExTextBox), new FrameworkPropertyMetadata('●'));/// <summary>/// 替换明文的单个密码字符/// </summary>public char PasswordChar{get { return (char)GetValue(PasswordCharProperty); }set { SetValue(PasswordCharProperty, value); }}public static DependencyProperty PasswordStrProperty =DependencyProperty.Register("PasswordStr", typeof(string), typeof(ExTextBox), new FrameworkPropertyMetadata(string.Empty));/// <summary>/// 密码字符串/// </summary>public string PasswordStr{get { return GetValue(PasswordStrProperty).ToString(); }set { SetValue(PasswordStrProperty, value); }}/// <summary>/// 图标大小/// </summary>public double ImageSize{get { return (double)GetValue(ImageSizeProperty); }set { SetValue(ImageSizeProperty, value); }}public static readonly DependencyProperty ImageSizeProperty =DependencyProperty.Register("ImageSize", typeof(double), typeof(ExTextBox),new FrameworkPropertyMetadata(26.0, FrameworkPropertyMetadataOptions.AffectsRender));public static readonly DependencyProperty TipImageProperty = DependencyProperty.Register("TipImage",typeof(string),typeof(ExTextBox),new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender, ImageSourceChanged));/// <summary>/// /// <summary>public string TipImage{get { return (string)GetValue(TipImageProperty); }set { SetValue(TipImageProperty, value); }}public static readonly DependencyProperty OperateImageProperty = DependencyProperty.Register("OperateImage",typeof(string),typeof(ExTextBox),new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender, ImageSourceChanged));/// <summary>/// /// <summary>public string OperateImage{get { return (string)GetValue(OperateImageProperty); }set { SetValue(OperateImageProperty, value); }}public static readonly DependencyProperty TipImageHideProperty = DependencyProperty.Register("TipImageHide",typeof(Visibility),typeof(ExTextBox),new FrameworkPropertyMetadata(Visibility.Collapsed));/// <summary>/// /// <summary>public Visibility TipImageHide{get { return (Visibility)GetValue(TipImageHideProperty); }set { SetValue(TipImageHideProperty, value); }}public static readonly DependencyProperty OperateHideProperty = DependencyProperty.Register("OperateHide",typeof(Visibility),typeof(ExTextBox),new FrameworkPropertyMetadata(Visibility.Collapsed));/// <summary>/// /// <summary>public Visibility OperateHide{get { return (Visibility)GetValue(OperateHideProperty); }set { SetValue(OperateHideProperty, value); }}//依赖属性发生改变时候触发private static void ImageSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e){Application.GetResourceStream(new Uri((string)e.NewValue));if(e.Property.Name == "TipImage"){(sender as ExTextBox).TextBox_Changed(0);}if (e.Property.Name == "OperateImage"){(sender as ExTextBox).TextBox_Changed(1);}}private void TextBox_Changed(int index){if (index == 0)TipImageHide = Visibility.Visible;elseOperateHide = Visibility.Visible;}//4.当设置为密码框时,监听TextChange事件,处理Text的变化,这是密码框的核心功能private static void OnIsPasswordBoxChnage(DependencyObject sender, DependencyPropertyChangedEventArgs e){(sender as ExTextBox).SetEvent();}/// <summary>/// 定义TextChange事件/// </summary>private void SetEvent(){if (IsPasswordBox)this.TextChanged += TextBox_TextChanged;elsethis.TextChanged -= TextBox_TextChanged;}//5.在TextChange事件中,处理Text为密码文,并将原字符记录给PasswordStr予以存储private void TextBox_TextChanged(object sender, TextChangedEventArgs e){if (!IsResponseChange) //响应事件标识,替换字符时,不处理后续逻辑return;//Console.WriteLine(string.Format("------{0}------", e.Changes.Count));foreach (TextChange c in e.Changes){//Console.WriteLine(string.Format("addLength:{0} removeLenth:{1} offSet:{2}", c.AddedLength, c.RemovedLength, c.Offset));PasswordStr = PasswordStr.Remove(c.Offset, c.RemovedLength); //从密码文中根据本次Change对象的索引和长度删除对应个数的字符PasswordStr = PasswordStr.Insert(c.Offset, Text.Substring(c.Offset, c.AddedLength));   //将Text新增的部分记录给密码文lastOffset = c.Offset;}//Console.WriteLine(PasswordStr);/*将文本转换为密码字符*/IsResponseChange = false;  //设置响应标识为不响应this.Text = ConvertToPasswordChar(Text.Length);  //将输入的字符替换为密码字符IsResponseChange = true;   //回复响应标识this.SelectionStart = lastOffset + 1; //设置光标索引//Console.WriteLine(string.Format("SelectionStar:{0}", this.SelectionStart));}/// <summary>/// 按照指定的长度生成密码字符/// </summary>/// <param name="length"></param>/// <returns></returns>private string ConvertToPasswordChar(int length){if (PasswordBuilder != null)PasswordBuilder.Clear();elsePasswordBuilder = new StringBuilder();for (var i = 0; i < length; i++)PasswordBuilder.Append(PasswordChar);return PasswordBuilder.ToString();}//6.如果用户设置了记住密码,密码文(PasswordStr)一开始就有值的话,别忘了在Load事件里事先替换一次明文private void ExTextBox_Loaded(object sender, RoutedEventArgs e){if (IsPasswordBox){IsResponseChange = false;this.Text = ConvertToPasswordChar(PasswordStr.Length);IsResponseChange = true;}}private bool IsResponseChange = true;private StringBuilder PasswordBuilder;private int lastOffset = 0;}

外部调用示例代码

<StackPanel VerticalAlignment="Center" ><TextBlock Text="水印密码输入框" FontSize="25" TextAlignment="Center"/><local:ExTextBox Height="40" BorderCornerRadius="5" Margin="10,10" Background="White"IsPasswordBox="False" PasswordStr="{Binding Password}" FontSize="20"/><local:ExTextBox Height="40" BorderCornerRadius="5" Margin="10,10" Background="White" WaterRemark="普通水印文本框"IsPasswordBox="True" PasswordStr="{Binding Password}" FontSize="20"/><!--水印文本框--><local:ExTextBox Height="40" BorderCornerRadius="5" Margin="10,10" Background="White" WaterRemark="带删除普通水印文本框"IsPasswordBox="False" PasswordStr="{Binding Password}" FontSize="20"OperateImage="Pack://application:,,,/ExPasswordBox;component/Images/delete.png"/><!--水印密码框--><local:ExTextBox  Height="40" BorderCornerRadius="5" Margin="10,10" Background="LightBlue" WaterRemark="密码输入框"BorderBrush="Red" FontSize="20" ImageSize="32"TipImage="Pack://application:,,,/ExPasswordBox;component/Images/man.png"OperateImage="Pack://application:,,,/ExPasswordBox;component/Images/delete.png"/>
</StackPanel>

效果图:

posted on 2019-04-10 11:26 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10682369.html

WPF 带水印的密码输入框实现相关推荐

  1. WPF 带CheckBox、图标的TreeView

    WPF 带CheckBox.图标的TreeView 在WPF实际项目开发的时候,经常会用到带CheckBox的TreeView,虽然微软在WPF的TreeView中没有提供该功能,但是微软在WPF中提 ...

  2. js 通过 exceljs 和 canvas 实现导出带水印的 excel 表

    因公司需求改动, 但是因为到的地方比较多,所以单独写一个单工作表导出,实际可用多工作表的代码部分 interface IHeader {k: string;v: string; } export in ...

  3. 使用docx4j生成指定页码的带水印的空白word文档

    使用docx4j生成指定页码的带水印的空白word文档 依赖========================================== org.docx4j docx4j 6.0.1 org ...

  4. 【微信小程序云开发】使用云函数(node.js)实现多张图片转成pdf的功能,且pdf带水印

    最近在做项目的时候,碰到一个功能需要多张图片转成pdf的功能,首先,在网上找了很多资料,都没有一个合适的. 后来,就自己动手使用云函数写了一个处理图片转成pdf的云函数,而且需带水印. 直奔主题,使用 ...

  5. 怎样录屏不带水印?分享一款无水印录制视频软件!

    案例:怎样录制无水印的视频? [我平常录制的录屏带有软件自带水印,这样十分影响观感.怎样才能录制无水印的视频?] 一款好的录屏软件,可以更好地帮助我们录制电脑屏幕上的操作或是制作教学视频.然而,很多录 ...

  6. 视频怎么加水印?如何录制带水印的视频?

    案例:如何给视频添加水印? [我发布在短视频平台的视频,总是被别人盗用,我想给自己的视频添加水印.有没有视频添加水印的方法?在线等!] 很多视频制作者或者爱好者,都希望自己的视频作品得到更多的认可和保 ...

  7. 如何保存小红书图片不带水印

    如何保存小红书图片不带水印,相信很多朋友会遇到这个问题,但却不知道怎么解决.今天就教大家如何保存无水印图片.这个工具通过创新的技术和产品设计,内容创作者可通过小红书笔记链接,解析出无水印图片视频文案素 ...

  8. 京东主图水印怎么去掉,怎么批量下载图片不带水印

    京东图片怎样批量保存没有水印的图片 怎么批量去掉京东图片水印 轻松批量去除京东商品视频的水印,批量下载保存的同时去除水印 京东商城上的图片,批量保存而不带水印,如果能有一个方法,可以批量下载,在下载的 ...

  9. 如何利用你电脑里的Photoshop软件来制作带水印的图片呢?

    首先说明一下,我也不是很会photoshop,只是用到就学些,慢慢积累就掌握了 好了开始表演,准备道具及素材,经验来自于百度经验的一篇文章:https://jingyan.baidu.com/arti ...

最新文章

  1. android游戏开发者大会,第二届中国Android应用开发大会将开
  2. python opencv教程rtsp server_Python多进程opencv调用rtsp视频流
  3. Setting Up Hadoop NameNode High Availability
  4. therefore/so/hence/then/accordingly/Thus
  5. delay在java中有什么用_java中DelayQueue的使用
  6. Spring集成activeMQ
  7. gsp 页面 html.dat,grails2.3.x在gsp显示html
  8. ActiveMQ学习总结(9)——Linux中安装ActiveMQ
  9. BI分析受阻?FineBI推出SPA螺旋式分析新功能!
  10. iOS添加自定义转场动画和交互动画(一)
  11. android7.0 netd与netlink的framework,kernel通信流程
  12. Android【报错】xxx cannot be resolved to a type 错误解决方法
  13. Git----远程仓库之添加远程库02
  14. 【React】第八部分 react脚手架安装以及react脚手架配置代理
  15. window10笔记本安装USB转VGA驱动,电脑重启后无法开机
  16. Managed Beans
  17. TALIB 中文文档 Volume Indicators 成交量指标
  18. 澳大利亚莫纳什大学推出公开漏洞奖励计划
  19. HTML5输入框里加图片代码,做了一个input上传加号框,图片上传后显示在框中,怎么让加号消失?...
  20. git基本命令使用大全

热门文章

  1. Win8/Win8.1常见错误代码的解决方法汇总
  2. 数据量高并发的数据库优化
  3. 守护进程(setsid、getpgrp、setpgid、getpgid)以及系统日志(openlog、syslog、closelog)...
  4. win 开机 Microsoft corparation 滚动栏
  5. 利用CSS定位背景图片
  6. TCP滑动窗口 - 动画演示
  7. CentOS 6.3 运维监控之Cacti 监控主机系统(二)
  8. 路由器配置与管理完全手册(H3C篇)学习感想
  9. google的阴阳历转换查询
  10. Python3 AttributeError: module 'cv2' has no attribute 'SIFT'