通过自定义属性与自定义行为实现Passwordbox的双向绑定

通过自定义属性与自定义行为实现Passwordbox的双向绑定-wpf精品免费课程_哔哩哔哩_bilibili
点击关注不迷路,你的关注是我们最大的动力。
原始的passwordbox控件为什么不能实现双向绑定?

因为PasswordBox的密码值不是通过标准的绑定机制暴露出来的。这是出于安全考虑,以防止密码在绑定过程中被截获。所以我们要通过附加属性和行为的方式来实现

一、创建PasswordBox的附加属性类

在项目中添加一个文件夹common,之后创建一个类 PasswordBoxExt.cs

在里面实现如下代码:

public static  class PasswordBoxHelper
 {
     public static readonly DependencyProperty BindPasswordProperty =
         DependencyProperty.RegisterAttached(
             "BindPwd",
             typeof(string),
             typeof(PasswordBoxHelper),
             new FrameworkPropertyMetadata(string.Empty, OnBindPasswordChanged));

     public static string GetBindPwd(DependencyObject dp)
     {
         return (string)dp.GetValue(BindPasswordProperty);
     }

     public static void SetBindPwd(DependencyObject dp, string value)
     {
         dp.SetValue(BindPasswordProperty, value);
     }

     public static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
     {
         PasswordBox passwordBox = dp as PasswordBox;
         if (passwordBox == null) return;

         string oldPassword = e.OldValue as string;
         string newPassword = e.NewValue as string;

         if (passwordBox.Password != newPassword)
         {
             passwordBox.Password = newPassword;
         }
         if (passwordBox.Password.Length < 5)
         {
             MessageBox.Show("密码强度不够");
         }

         passwordBox.PasswordChanged += PasswordBox_PasswordChanged;
     }

      static void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
     {
         PasswordBox passwordBox = sender as PasswordBox;
         if (passwordBox == null) return;

         string password = passwordBox.Password;
         SetBindPwd(passwordBox, password);
     }
 }

二、在应用UI层做如下改动

xmlns:local="clr-namespace:MyAgvLesson.ViewModel" 
  xmlns:pass="clr-namespace:MyAgvLesson.Common"

注意,这个local的DataContext上一节课是放在了后台隐藏代码里,这里我们还可以把他放在前台。如下

 <Window.DataContext>
     <local:UserViewModel></local:UserViewModel>
 </Window.DataContext>

然后我们就可以对PasswordBox这个控件做如下处理:

 <PasswordBox pass:PasswordBoxHelper.BindPwd="{Binding Password, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"     Height="30" Padding="5" DockPanel.Dock="Top" Margin="0 10 0 0">

这样就可以实现PasswordBox的mvvm下的双向绑定。但是我们在这个属性里做了 passwordBox.PasswordChanged += PasswordBox_PasswordChanged;这个操作,这个其实没有解耦的,所以我们采用行为把他们进行分离。

三、使行Behavior为控件定义自己定义行为

还是在上面那个ext.js里,创建一个类,代码如下:

 public class PasswordBehavior: Behavior<PasswordBox>
 {
     protected override void OnAttached()
     {
         base.OnAttached();
         AssociatedObject.PasswordChanged += AssociatedObject_PasswordChanged;
     }

     private void AssociatedObject_PasswordChanged(object sender, RoutedEventArgs e)
     {
        var password=e.Source as PasswordBox;
        string pwd=PasswordBoxHelper.GetBindPwd(password);
      
         if (pwd != null&& password.Password!=pwd)
         {
             PasswordBoxHelper.SetBindPwd(password, password.Password);
         }
     }

     protected override void OnDetaching() { 
    base.OnDetaching();
         AssociatedObject.PasswordChanged-= AssociatedObject_PasswordChanged;
     }
 }

这个继承的Behavior要在Nuget里安装Microsoft.Xaml.Behaviors这个包。

然后在UI里面添加:

xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

之后在password里添加:

  <PasswordBox pass:PasswordBoxHelper.BindPwd="{Binding Password, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"     Height="30" Padding="5" DockPanel.Dock="Top" Margin="0 10 0 0">
        <i:Interaction.Behaviors>
            <pass:PasswordBehavior/>
        </i:Interaction.Behaviors>
    </PasswordBox>

这样就实现了通过自定义的属性与自定义行为实现了passwordBox的双向绑定了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值