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; } } }
标签:PasswordChanged,sender,PasswordBox,绑定,密码,static,passwordBox,WPF,dp 来源: https://blog.51cto.com/u_11283245/2954153