WPF PasswordBox的数据绑定功能处理

当我们输入的敏感信息时,用到最多的就是使用PasswordBox。但是由于某些原因或考虑,wpf的标准并不支持Binding方法。PasswordBox的属性只是一个普通的CLR属性,并不是Dependency 属性。

幸运的是,wpf具有附加属性的概念,允许我们更加容易的进行控件的扩展。下面就使用附加属性进行处理PasswordBox的绑定功能

使用方法如下

<Page xmlns:ff="clr-namespace:FunctionalFun.UI">
  <!-- [Snip] -->
  <PasswordBox x:Name="PasswordBox"
      ff:PasswordBoxAssistant.BindPassword="true"  ff:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</Page>

设定BindPassword属性为True,这样代码就会在PasswordBox上侦听PasswordChanged事件,只要当PasswordBox的内容有更改,代码就会把更改的新的值推送到附加属性:BoundPassword中,然后把要绑定的值绑定到BoundPassword中。唯一复杂的就是要确保整个事件不会递归和UpdatingPassword私有属性

using System.Windows;
using System.Windows.Controls;
 
namespace FunctionalFun.UI
{
  public static class PasswordBoxAssistant
  {
      public static readonly DependencyProperty BoundPassword =
          DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxAssistant), new PropertyMetadata(string.Empty, OnBoundPasswordChanged));
 
      public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
          "BindPassword", typeof (bool), typeof (PasswordBoxAssistant), new PropertyMetadata(false, OnBindPasswordChanged));
 
      private static readonly DependencyProperty UpdatingPassword =
          DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false));
 
      private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
          PasswordBox box = d as PasswordBox;
 
          // only handle this event when the property is attached to a PasswordBox
          // and when the BindPassword attached property has been set to true
          if (d == null || !GetBindPassword(d))
          {
              return;
          }
 
          // avoid recursive updating by ignoring the box's changed event
          box.PasswordChanged -= HandlePasswordChanged;
 
          string newPassword = (string)e.NewValue;
 
          if (!GetUpdatingPassword(box))
          {
              box.Password = newPassword;
          }
 
          box.PasswordChanged += HandlePasswordChanged;
      }
 
      private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
      {
          // when the BindPassword attached property is set on a PasswordBox,
          // start listening to its PasswordChanged event
 
          PasswordBox box = dp as PasswordBox;
 
          if (box == null)
          {
              return;
          }
 
          bool wasBound = (bool)(e.OldValue);
          bool needToBind = (bool)(e.NewValue);
 
          if (wasBound)
          {
              box.PasswordChanged -= HandlePasswordChanged;
          }
 
          if (needToBind)
          {
              box.PasswordChanged += HandlePasswordChanged;
          }
      }
 
      private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
      {
          PasswordBox box = sender as PasswordBox;
 
          // set a flag to indicate that we're updating the password
          SetUpdatingPassword(box, true);
          // push the new password into the BoundPassword property
          SetBoundPassword(box, box.Password);
          SetUpdatingPassword(box, false);
      }
 
      public static void SetBindPassword(DependencyObject dp, bool value)
      {
          dp.SetValue(BindPassword, value);
      }
 
      public static bool GetBindPassword(DependencyObject dp)
      {
          return (bool)dp.GetValue(BindPassword);
      }
 
      public static string GetBoundPassword(DependencyObject dp)
      {
          return (string)dp.GetValue(BoundPassword);
      }
 
      public static void SetBoundPassword(DependencyObject dp, string value)
      {
          dp.SetValue(BoundPassword, value);
      }
 
      private static bool GetUpdatingPassword(DependencyObject dp)
      {
          return (bool)dp.GetValue(UpdatingPassword);
      }
 
      private static void SetUpdatingPassword(DependencyObject dp, bool value)
      {
          dp.SetValue(UpdatingPassword, value);
      }
  }
}

原文 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值