WPF中实现PasswordBox的双向绑定

我们知道一个属性想要实现双向绑定,最基本的便是这个属性需要时依赖属性,但是微软工程师在设计的时候Password并不是依赖属性,那我们想要实现双向绑定该怎么去做呢?

最常用的便是改造PasswordBox,为它增加一个扩展属性,借助扩展属性实现Password的读写功能。

首先我们建一个PasswordBoxExtend的扩展类,输入快捷语句"propa",然后按下"Tap"键,即可自动生成我们需要的所有函数。

之后我们改变一些主要内容

cs 复制代码
public static string GetPwd(DependencyObject obj)
{
    return (string)obj.GetValue(PwdProperty);
}

public static void SetPwd(DependencyObject obj, string value)
{
    obj.SetValue(PwdProperty, value);
}

      
public static readonly DependencyProperty PwdProperty =
    DependencyProperty.RegisterAttached("Pwd", typeof(string), typeof(PasswordBoxExtend), new PropertyMetadata("", OnPwdChanged));

/// <summary>
/// 密码属性变化事件
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private static void OnPwdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    string newPwd = (string)e.NewValue;
    if (d is PasswordBox passwordBox && passwordBox.Password != newPwd)
    {
        passwordBox.Password = newPwd;
    }
}

这样就实现了当我们的附加属性发现变化的时候就会修改我们Password的值,但是我们Password的值改变后并不会通知我们附加属性,所以我们还需要建立一个PasswordBoxBehaviors行为事件类,让它继承Behavior,从而实现当Password改变时通知到我们的附加属性

cs 复制代码
/// <summary>
/// PasswordBox行为
/// 当Password变化时,触发自定义属性跟着变化
/// </summary>
public class PasswordBoxBehaviors : Behavior<PasswordBox>
{
    /// <summary>
    /// 附加行为
    /// 注入事件
    /// </summary>
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.PasswordChanged += OnPasswordChanged;
    }

    private void OnPasswordChanged(object sender, RoutedEventArgs e)
    {
        PasswordBox passwordBox = sender as PasswordBox;
        string password = PasswordBoxExtend.GetPwd(passwordBox);
        if (passwordBox!= null && password != passwordBox.Password)
        {
            PasswordBoxExtend.SetPwd(passwordBox, passwordBox.Password);
        }
    }

    /// <summary>
    /// 销毁行为
    /// 移除事件
    /// </summary>
    protected override void OnDetaching()
    {
        base.OnDetaching();
        this.AssociatedObject.PasswordChanged -= OnPasswordChanged;
    }
}

然后我们在ViewModel中第一密码变量

cs 复制代码
 /// <summary>
 /// 密码
 /// </summary>
 private string _Pwd;
 public string Pwd
 {
     get { return _Pwd; }
     set { _Pwd = value; }
 }

最后在前端绑定即可

XML 复制代码
<PasswordBox
    Margin="0,10"
    md:HintAssist.Hint="请输入密码"
    pwdExtend:PasswordBoxExtend.Pwd="{Binding Pwd, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    DockPanel.Dock="Top">
    <!--绑定行为-->
    <i:Interaction.Behaviors>
        <pwdExtend:PasswordBoxBehaviors />
    </i:Interaction.Behaviors>
</PasswordBox>
相关推荐
唐青枫10 小时前
别把日志、权限写进业务方法:C#.NET 动态代理从原理到实战
c#·.net
风云10 小时前
Vane.Dispatch 1.0.0 发布:一个与容器、传输层零耦合的 .NET 服务分发引擎
微服务·mvc·.net·ndf·vane.dispatch
fujisheng66111 小时前
Unity UI 生命周期状态机:处理 Covered、异步竞态与事务回滚
c#·unity3d
leoZ23116 小时前
第 8 篇:与 AI 协作的工作流 + 完整案例
前端·人工智能·神经网络·自然语言处理·性能优化·c#·php
fujisheng66118 小时前
Unity 异步 UI 实战:取消令牌、版本校验与旧句柄隔离
c#·unity3d
额鹅恶饿呃19 小时前
随着CentOS官方停服的时间越来越久,大量仍在使用CentOS7的企业和运维从业者
java·python·算法·c#·ruby
乌药ice19 小时前
c#中一个多线程安全的HashSet
开发语言·c#
lfSeanDragon19 小时前
数据结构-前缀树(Trie)
开发语言·c#
张人玉20 小时前
基于 C# WinForms + .NET 8 + SQLite + TCP Socket 的多连接通讯调试工具——TCP通讯助手(TcpAssistant)
tcp/ip·sqlite·c#·.net
mldong1 天前
C# 开发者也有自己的轻量工作流引擎了:NuGet 装包,5 分钟跑通一条审批流
后端·c#·.net