2018-2-13-WPF-绑定密码
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 ,他是一个静态类,当然不是静态也没关系,但是一般写静态的可以让我们少犯错,因为我们所有属性等都是需要静态的。
- public static class PasswordHelper
- {
- public static readonly DependencyProperty PasswordProperty =
- DependencyProperty.RegisterAttached("Password",
- typeof(string), typeof(PasswordHelper),
- new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));
- public static readonly DependencyProperty AttachProperty =
- DependencyProperty.RegisterAttached("Attach",
- typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, Attach));
- private static readonly DependencyProperty IsUpdatingProperty =
- DependencyProperty.RegisterAttached("IsUpdating", typeof(bool),
- typeof(PasswordHelper));
- public static void SetAttach(DependencyObject dp, bool value)
- {
- dp.SetValue(AttachProperty, value);
- }
- public static bool GetAttach(DependencyObject dp)
- {
- return (bool)dp.GetValue(AttachProperty);
- }
- public static string GetPassword(DependencyObject dp)
- {
- return (string)dp.GetValue(PasswordProperty);
- }
- public static void SetPassword(DependencyObject dp, string value)
- {
- dp.SetValue(PasswordProperty, value);
- }
- private static bool GetIsUpdating(DependencyObject dp)
- {
- return (bool)dp.GetValue(IsUpdatingProperty);
- }
- private static void SetIsUpdating(DependencyObject dp, bool value)
- {
- dp.SetValue(IsUpdatingProperty, value);
- }
- private static void OnPasswordPropertyChanged(DependencyObject sender,
- DependencyPropertyChangedEventArgs e)
- {
- PasswordBox passwordBox = sender as PasswordBox;
- if (passwordBox != null)
- {
- passwordBox.PasswordChanged -= PasswordChanged;
- if (!(bool)GetIsUpdating(passwordBox))
- {
- passwordBox.Password = (string)e.NewValue;
- }
- passwordBox.PasswordChanged += PasswordChanged;
- }
- }
- private static void Attach(DependencyObject sender,
- DependencyPropertyChangedEventArgs e)
- {
- PasswordBox passwordBox = sender as PasswordBox;
- if (passwordBox == null)
- return;
- if ((bool)e.OldValue)
- {
- passwordBox.PasswordChanged -= PasswordChanged;
- }
- if ((bool)e.NewValue)
- {
- passwordBox.PasswordChanged += PasswordChanged;
- }
- }
- private static void PasswordChanged(object sender, RoutedEventArgs e)
- {
- PasswordBox passwordBox = sender as PasswordBox;
- if (passwordBox != null)
- {
- SetIsUpdating(passwordBox, true);
- SetPassword(passwordBox, passwordBox.Password);
- SetIsUpdating(passwordBox, false);
- }
- }
- }
写完我们就可以使用他,使用很简单,在我们需要密码框的页面的xaml 上写两行新的代码就好。
- <PasswordBox local:PasswordHelper.Attach="True"
- local:PasswordHelper.Password="{Binding Password, Mode=TwoWay}"
- Width="180" Style="{DynamicResource PasswordBoxStyle}"/>
其中,Password 是 ViewModel 的PassWord,很简单我们把PasswordBox 绑定到ViewModel。
PASSWORDPROPERTY是附加属性,REGISTERATTACHED 就是注册附加。
我们附加属性是回调,当属性变化使用函数。
我们需要设置Attach,设置时调用static void Attach(DependencyObject sender, DependencyPropertyChangedEventArgs e)
在 Attach 触发,首先要判断设置的 sender 是不是 Password
- PasswordBox passwordBox = sender as PasswordBox;
- if (passwordBox == null)
- {
- return;
- }
判断改变的值,Old是true还是false,如果是true,那么之前用了事件,我们要把事件
- passwordBox.PasswordChanged -= PasswordChanged;
如果之前是false,那么没绑定,我们不能删除。
判断要改变的,如果是true,我们就
- passwordBox.PasswordChanged += PasswordChanged;
如果不是,我们就不使用。
我们使用了是否存在密码修改就使用PasswordChanged函数。也就是设置了刚才的就可在密码变化使用PasswordChanged。
我们在PasswordChanged判断输入是不是PasswordBox,把密码传进PasswordProperty。
参见:http://www.wpftutorial.net/PasswordBox.html
还有一个简单方法
<script src="https://gist.github.com/taylorleese/468331.js"></script>
- using System.Windows;
- using System.Windows.Controls;
- namespace CustomControl
- {
- public class BindablePasswordBox : Decorator
- {
- /// <summary>
- /// The password dependency property.
- /// </summary>
- public static readonly DependencyProperty PasswordProperty;
- private bool isPreventCallback;
- private RoutedEventHandler savedCallback;
- /// <summary>
- /// Static constructor to initialize the dependency properties.
- /// </summary>
- static BindablePasswordBox()
- {
- PasswordProperty = DependencyProperty.Register(
- "Password",
- typeof(string),
- typeof(BindablePasswordBox),
- new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnPasswordPropertyChanged))
- );
- }
- /// <summary>
- /// Saves the password changed callback and sets the child element to the password box.
- /// </summary>
- public BindablePasswordBox()
- {
- savedCallback = HandlePasswordChanged;
- PasswordBox passwordBox = new PasswordBox();
- passwordBox.PasswordChanged += savedCallback;
- Child = passwordBox;
- }
- /// <summary>
- /// The password dependency property.
- /// </summary>
- public string Password
- {
- get { return GetValue(PasswordProperty) as string; }
- set { SetValue(PasswordProperty, value); }
- }
- /// <summary>
- /// Handles changes to the password dependency property.
- /// </summary>
- /// <param name="d">the dependency object</param>
- /// <param name="eventArgs">the event args</param>
- private static void OnPasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs eventArgs)
- {
- BindablePasswordBox bindablePasswordBox = (BindablePasswordBox) d;
- PasswordBox passwordBox = (PasswordBox) bindablePasswordBox.Child;
- if (bindablePasswordBox.isPreventCallback)
- {
- return;
- }
- passwordBox.PasswordChanged -= bindablePasswordBox.savedCallback;
- passwordBox.Password = (eventArgs.NewValue != null) ? eventArgs.NewValue.ToString() : "";
- passwordBox.PasswordChanged += bindablePasswordBox.savedCallback;
- }
- /// <summary>
- /// Handles the password changed event.
- /// </summary>
- /// <param name="sender">the sender</param>
- /// <param name="eventArgs">the event args</param>
- private void HandlePasswordChanged(object sender, RoutedEventArgs eventArgs)
- {
- PasswordBox passwordBox = (PasswordBox) sender;
- isPreventCallback = true;
- Password = passwordBox.Password;
- isPreventCallback = false;
- }
- }
- }
2018-2-13-WPF-绑定密码的更多相关文章
- WPF 绑定密码
我们发现我们无法绑定密码框的密码,PasswordBox 的 Password 不能绑定. 我们想做 MVVM ,我们需要绑定密码,不能使用前台 xaml.cs 监听 密码改变得到密码的值,传到 Vi ...
- win10 uwp 绑定密码
win10 下,密码框无法绑定到ViewModel,Password是不可以绑定. 我们可以自己使用简单方法去绑定 我们之前在WPF 使用绑定密码框,我写了一篇,关于如何绑定,我提供一个我自己试了可以 ...
- WPF快速入门系列(4)——深入解析WPF绑定
一.引言 WPF绑定使得原本需要多行代码实现的功能,现在只需要简单的XAML代码就可以完成之前多行后台代码实现的功能.WPF绑定可以理解为一种关系,该关系告诉WPF从一个源对象提取一些信息,并将这些信 ...
- WPF绑定的ListBox获取ListBoxItem及GoToState应用
现公司项目中需要制作一个扇形菜单,菜单项是用ListBox重写Style实现的,其数据是绑定的.菜单的每一项都有Normal,MouseOver和Selected三种状态,这三种状态当然可以通过鼠标移 ...
- WPF绑定文本时使用指定格式文本
原文:WPF绑定文本时使用指定格式文本 Text="{Binding PlayletModel.characters,StringFormat=Cast : {0}}" Strin ...
- (转)新手C#SQL语句的学习2018.08.13
1.创建数据库(create) CREATE DATABASE database-name 2.删除数据库(drop) drop database dbname 3.备份数据库 --- 创建 备份数据 ...
- WPF绑定之索引器值变化通知
背景 在某些应用中,需要在界面上绑定到索引器,并在值发生变化时实时更新. 解决方案 只要将包含索引器的类实现INotifyPropertyChanged接口,并在索引值更改时引发PropertyCha ...
- WPF 绑定StaticResource到控件的方法
原文:WPF 绑定StaticResource到控件的方法 资源文件内的属性能否直接通过绑定应用到控件?答案是肯定的. 比如,我们要直接把下面的<SolidColorBrush x:Key=&q ...
- WPF 绑定以基础数据类型为集合的无字段名的数据源
WPF 绑定以基础数据类型为集合的无字段名的数据源 运行环境:Window7 64bit,.NetFramework4.61,C# 6.0: 编者:乌龙哈里 2017-02-21 我们在控件的数据绑定 ...
- WPF绑定xaml中绑定对象需用属性表示,字段不可以绑定
在练习WPF绑定时发现对象属性可以在XAML中绑定,但字段是不可以绑定: 比如: private Person person{get;set;} 可以绑定到XAML中,<TextBox Nam ...
随机推荐
- alert(1) to win 12
- Wannafly挑战赛27 D绿魔法师
链接Wannafly挑战赛27 D绿魔法师 一个空的可重集合\(S\),\(n\)次操作,每次操作给出\(x,k,p\),要求支持下列操作: 1.在\(S\)中加入\(x\). 2.求\[\sum_{ ...
- macaca搭建
对于新鲜的事务总是那么好奇,在自动化的过程中,有幸了解到macaca,记录下安装过程,具体介绍请移步官网:https://github.com/macacajs/ python版本参考:https:/ ...
- hdu 6053: TrickGCD (2017 多校第二场 1009) 【莫比乌斯 容斥原理】
题目链接 定义f[n]表示n是最大公约数情况下的计数,F[n]为n是公约数情况下的计数 (可以和 http://www.cnblogs.com/Just--Do--It/p/7197788.html ...
- 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 ...
- 在linux中 部署 mongo 数据库服务端
1 首先需要一台linux服务器(我用的redhat linux,其它的也大同小异), 玩一玩的话,推荐亚马逊上面去创建一个免费的linux服务器,有关具体创建linux服务器不在这赘述. https ...
- ueditor编辑器中从word中复制带图片的信息的操作演示
我司需要做一个需求,就是使用富文本编辑器时,不要以上传附件的形式上传图片,而是以复制粘贴的形式上传图片. 在网上找了一下,有一个插件支持这个功能. WordPaster 安装方式如下: 直接使用Wor ...
- 【テンプレート】LCA
LCA目前比较流行的算法主要有tarjian,倍增和树链剖分 1)tarjian 是一种离线算法,需要提前知道所有询问对 算法如下 1.读入所有询问对(u,v),并建好树(建议邻接表) 2.初始化每个 ...
- Centos7防火墙和SELinux的开启和关闭
在虚拟机里面开启多个服务,对应多个端口,在防火墙开启的情况下,就要对外开放端口,这样客户端才能正常访问,但比较繁琐,关闭更直接点. 防火墙 临时关闭防火墙 systemctl stop firewal ...
- 转载:TypeError: Cannot read property 'compilation' of undefined vue 打包运行npm run build 报错
转载自:https://www.jianshu.com/p/3f8f60e01797 运行npm run build打包时,报错如下: 我的package.json如下: { ... " ...