title author date CreateTime categories
WPF 绑定密码
lindexi
2018-2-13 17:23:3 +0800
2018-2-13 17:23:3 +0800
WPF

我们发现我们无法绑定密码框的密码,PasswordBox 的 Password 不能绑定。
我们想做 MVVM ,我们需要绑定密码,不能使用前台 xaml.cs 监听 密码改变得到密码的值,传到 ViewModel 。
本文提供一个简单方法来绑定 WPF 的 PasswordBox 的 Password 。这种方法不仅在 WPF 可以使用,在 UWP 也可以使用。关于 UWP 绑定密码,可以在我博客 win10 uwp 绑定密码 查看。

我在网上找的很多大神给出的可以解决绑定密码的方法,下面是我找的一个简单方法。

首先需要新建一个类 PasswordHelper ,他是一个静态类,当然不是静态也没关系,但是一般写静态的可以让我们少犯错,因为我们所有属性等都是需要静态的。

  1. public static class PasswordHelper
  2. {
  3. public static readonly DependencyProperty PasswordProperty =
  4. DependencyProperty.RegisterAttached("Password",
  5. typeof(string), typeof(PasswordHelper),
  6. new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));
  7.  
  8. public static readonly DependencyProperty AttachProperty =
  9. DependencyProperty.RegisterAttached("Attach",
  10. typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, Attach));
  11.  
  12. private static readonly DependencyProperty IsUpdatingProperty =
  13. DependencyProperty.RegisterAttached("IsUpdating", typeof(bool),
  14. typeof(PasswordHelper));
  15.  
  16. public static void SetAttach(DependencyObject dp, bool value)
  17. {
  18. dp.SetValue(AttachProperty, value);
  19. }
  20.  
  21. public static bool GetAttach(DependencyObject dp)
  22. {
  23. return (bool)dp.GetValue(AttachProperty);
  24. }
  25.  
  26. public static string GetPassword(DependencyObject dp)
  27. {
  28. return (string)dp.GetValue(PasswordProperty);
  29. }
  30.  
  31. public static void SetPassword(DependencyObject dp, string value)
  32. {
  33. dp.SetValue(PasswordProperty, value);
  34. }
  35.  
  36. private static bool GetIsUpdating(DependencyObject dp)
  37. {
  38. return (bool)dp.GetValue(IsUpdatingProperty);
  39. }
  40.  
  41. private static void SetIsUpdating(DependencyObject dp, bool value)
  42. {
  43. dp.SetValue(IsUpdatingProperty, value);
  44. }
  45.  
  46. private static void OnPasswordPropertyChanged(DependencyObject sender,
  47. DependencyPropertyChangedEventArgs e)
  48. {
  49. PasswordBox passwordBox = sender as PasswordBox;
  50. if (passwordBox != null)
  51. {
  52. passwordBox.PasswordChanged -= PasswordChanged;
  53.  
  54. if (!(bool)GetIsUpdating(passwordBox))
  55. {
  56. passwordBox.Password = (string)e.NewValue;
  57. }
  58. passwordBox.PasswordChanged += PasswordChanged;
  59. }
  60. }
  61.  
  62. private static void Attach(DependencyObject sender,
  63. DependencyPropertyChangedEventArgs e)
  64. {
  65. PasswordBox passwordBox = sender as PasswordBox;
  66.  
  67. if (passwordBox == null)
  68. return;
  69.  
  70. if ((bool)e.OldValue)
  71. {
  72. passwordBox.PasswordChanged -= PasswordChanged;
  73. }
  74.  
  75. if ((bool)e.NewValue)
  76. {
  77. passwordBox.PasswordChanged += PasswordChanged;
  78. }
  79. }
  80.  
  81. private static void PasswordChanged(object sender, RoutedEventArgs e)
  82. {
  83. PasswordBox passwordBox = sender as PasswordBox;
  84. if (passwordBox != null)
  85. {
  86. SetIsUpdating(passwordBox, true);
  87. SetPassword(passwordBox, passwordBox.Password);
  88. SetIsUpdating(passwordBox, false);
  89. }
  90. }
  91. }

写完我们就可以使用他,使用很简单,在我们需要密码框的页面的xaml 上写两行新的代码就好。

  1. <PasswordBox local:PasswordHelper.Attach="True"
  2. local:PasswordHelper.Password="{Binding Password, Mode=TwoWay}"
  3. Width="180" Style="{DynamicResource PasswordBoxStyle}"/>

其中,Password 是 ViewModel 的PassWord,很简单我们把PasswordBox 绑定到ViewModel。

PASSWORDPROPERTY是附加属性,REGISTERATTACHED 就是注册附加。

我们附加属性是回调,当属性变化使用函数。

我们需要设置Attach,设置时调用static void Attach(DependencyObject sender, DependencyPropertyChangedEventArgs e)

在 Attach 触发,首先要判断设置的 sender 是不是 Password

  1. PasswordBox passwordBox = sender as PasswordBox;
  2.  
  3. if (passwordBox == null)
  4. {
  5. return;
  6. }

判断改变的值,Old是true还是false,如果是true,那么之前用了事件,我们要把事件

  1. passwordBox.PasswordChanged -= PasswordChanged;

如果之前是false,那么没绑定,我们不能删除。

判断要改变的,如果是true,我们就

  1. passwordBox.PasswordChanged += PasswordChanged;

如果不是,我们就不使用。

我们使用了是否存在密码修改就使用PasswordChanged函数。也就是设置了刚才的就可在密码变化使用PasswordChanged。

我们在PasswordChanged判断输入是不是PasswordBox,把密码传进PasswordProperty。

参见:http://www.wpftutorial.net/PasswordBox.html

还有一个简单方法

<script src="https://gist.github.com/taylorleese/468331.js"></script>

  1. using System.Windows;
  2. using System.Windows.Controls;
  3.  
  4. namespace CustomControl
  5. {
  6. public class BindablePasswordBox : Decorator
  7. {
  8. /// <summary>
  9. /// The password dependency property.
  10. /// </summary>
  11. public static readonly DependencyProperty PasswordProperty;
  12.  
  13. private bool isPreventCallback;
  14. private RoutedEventHandler savedCallback;
  15.  
  16. /// <summary>
  17. /// Static constructor to initialize the dependency properties.
  18. /// </summary>
  19. static BindablePasswordBox()
  20. {
  21. PasswordProperty = DependencyProperty.Register(
  22. "Password",
  23. typeof(string),
  24. typeof(BindablePasswordBox),
  25. new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnPasswordPropertyChanged))
  26. );
  27. }
  28.  
  29. /// <summary>
  30. /// Saves the password changed callback and sets the child element to the password box.
  31. /// </summary>
  32. public BindablePasswordBox()
  33. {
  34. savedCallback = HandlePasswordChanged;
  35.  
  36. PasswordBox passwordBox = new PasswordBox();
  37. passwordBox.PasswordChanged += savedCallback;
  38. Child = passwordBox;
  39. }
  40.  
  41. /// <summary>
  42. /// The password dependency property.
  43. /// </summary>
  44. public string Password
  45. {
  46. get { return GetValue(PasswordProperty) as string; }
  47. set { SetValue(PasswordProperty, value); }
  48. }
  49.  
  50. /// <summary>
  51. /// Handles changes to the password dependency property.
  52. /// </summary>
  53. /// <param name="d">the dependency object</param>
  54. /// <param name="eventArgs">the event args</param>
  55. private static void OnPasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs eventArgs)
  56. {
  57. BindablePasswordBox bindablePasswordBox = (BindablePasswordBox) d;
  58. PasswordBox passwordBox = (PasswordBox) bindablePasswordBox.Child;
  59.  
  60. if (bindablePasswordBox.isPreventCallback)
  61. {
  62. return;
  63. }
  64.  
  65. passwordBox.PasswordChanged -= bindablePasswordBox.savedCallback;
  66. passwordBox.Password = (eventArgs.NewValue != null) ? eventArgs.NewValue.ToString() : "";
  67. passwordBox.PasswordChanged += bindablePasswordBox.savedCallback;
  68. }
  69.  
  70. /// <summary>
  71. /// Handles the password changed event.
  72. /// </summary>
  73. /// <param name="sender">the sender</param>
  74. /// <param name="eventArgs">the event args</param>
  75. private void HandlePasswordChanged(object sender, RoutedEventArgs eventArgs)
  76. {
  77. PasswordBox passwordBox = (PasswordBox) sender;
  78.  
  79. isPreventCallback = true;
  80. Password = passwordBox.Password;
  81. isPreventCallback = false;
  82. }
  83. }
  84. }

2018-2-13-WPF-绑定密码的更多相关文章

  1. WPF 绑定密码

    我们发现我们无法绑定密码框的密码,PasswordBox 的 Password 不能绑定. 我们想做 MVVM ,我们需要绑定密码,不能使用前台 xaml.cs 监听 密码改变得到密码的值,传到 Vi ...

  2. win10 uwp 绑定密码

    win10 下,密码框无法绑定到ViewModel,Password是不可以绑定. 我们可以自己使用简单方法去绑定 我们之前在WPF 使用绑定密码框,我写了一篇,关于如何绑定,我提供一个我自己试了可以 ...

  3. WPF快速入门系列(4)——深入解析WPF绑定

    一.引言 WPF绑定使得原本需要多行代码实现的功能,现在只需要简单的XAML代码就可以完成之前多行后台代码实现的功能.WPF绑定可以理解为一种关系,该关系告诉WPF从一个源对象提取一些信息,并将这些信 ...

  4. WPF绑定的ListBox获取ListBoxItem及GoToState应用

    现公司项目中需要制作一个扇形菜单,菜单项是用ListBox重写Style实现的,其数据是绑定的.菜单的每一项都有Normal,MouseOver和Selected三种状态,这三种状态当然可以通过鼠标移 ...

  5. WPF绑定文本时使用指定格式文本

    原文:WPF绑定文本时使用指定格式文本 Text="{Binding PlayletModel.characters,StringFormat=Cast : {0}}" Strin ...

  6. (转)新手C#SQL语句的学习2018.08.13

    1.创建数据库(create) CREATE DATABASE database-name 2.删除数据库(drop) drop database dbname 3.备份数据库 --- 创建 备份数据 ...

  7. WPF绑定之索引器值变化通知

    背景 在某些应用中,需要在界面上绑定到索引器,并在值发生变化时实时更新. 解决方案 只要将包含索引器的类实现INotifyPropertyChanged接口,并在索引值更改时引发PropertyCha ...

  8. WPF 绑定StaticResource到控件的方法

    原文:WPF 绑定StaticResource到控件的方法 资源文件内的属性能否直接通过绑定应用到控件?答案是肯定的. 比如,我们要直接把下面的<SolidColorBrush x:Key=&q ...

  9. WPF 绑定以基础数据类型为集合的无字段名的数据源

    WPF 绑定以基础数据类型为集合的无字段名的数据源 运行环境:Window7 64bit,.NetFramework4.61,C# 6.0: 编者:乌龙哈里 2017-02-21 我们在控件的数据绑定 ...

  10. WPF绑定xaml中绑定对象需用属性表示,字段不可以绑定

    在练习WPF绑定时发现对象属性可以在XAML中绑定,但字段是不可以绑定: 比如: private Person person{get;set;}  可以绑定到XAML中,<TextBox Nam ...

随机推荐

  1. alert(1) to win 12

  2. Wannafly挑战赛27 D绿魔法师

    链接Wannafly挑战赛27 D绿魔法师 一个空的可重集合\(S\),\(n\)次操作,每次操作给出\(x,k,p\),要求支持下列操作: 1.在\(S\)中加入\(x\). 2.求\[\sum_{ ...

  3. macaca搭建

    对于新鲜的事务总是那么好奇,在自动化的过程中,有幸了解到macaca,记录下安装过程,具体介绍请移步官网:https://github.com/macacajs/ python版本参考:https:/ ...

  4. hdu 6053: TrickGCD (2017 多校第二场 1009) 【莫比乌斯 容斥原理】

    题目链接 定义f[n]表示n是最大公约数情况下的计数,F[n]为n是公约数情况下的计数 (可以和 http://www.cnblogs.com/Just--Do--It/p/7197788.html  ...

  5. Python3解leetcode Average of Levels in Binary Tree

    问题描述: Given a non-empty binary tree, return the average value of the nodes on each level in the form ...

  6. 在linux中 部署 mongo 数据库服务端

    1 首先需要一台linux服务器(我用的redhat linux,其它的也大同小异), 玩一玩的话,推荐亚马逊上面去创建一个免费的linux服务器,有关具体创建linux服务器不在这赘述. https ...

  7. ueditor编辑器中从word中复制带图片的信息的操作演示

    我司需要做一个需求,就是使用富文本编辑器时,不要以上传附件的形式上传图片,而是以复制粘贴的形式上传图片. 在网上找了一下,有一个插件支持这个功能. WordPaster 安装方式如下: 直接使用Wor ...

  8. 【テンプレート】LCA

    LCA目前比较流行的算法主要有tarjian,倍增和树链剖分 1)tarjian 是一种离线算法,需要提前知道所有询问对 算法如下 1.读入所有询问对(u,v),并建好树(建议邻接表) 2.初始化每个 ...

  9. Centos7防火墙和SELinux的开启和关闭

    在虚拟机里面开启多个服务,对应多个端口,在防火墙开启的情况下,就要对外开放端口,这样客户端才能正常访问,但比较繁琐,关闭更直接点. 防火墙 临时关闭防火墙 systemctl stop firewal ...

  10. 转载:TypeError: Cannot read property 'compilation' of undefined vue 打包运行npm run build 报错

    转载自:https://www.jianshu.com/p/3f8f60e01797 运行npm run build打包时,报错如下:   我的package.json如下: { ... " ...