WPF中Password绑定

原创 2024-03-23 16:19 厦门
文章的分类 .NET WPF

WPF中Password绑定

目录

前言

在WPF(Windows Presentation Foundation)中,密码框(PasswordBox)默认不支持数据绑定,因为它不是以明文形式存储密码,出于安全考虑。但是,我们可以通过附加属性(Attached Property)或者使用代码后台的方式来实现密码的数据绑定。

LoginWindow.xaml

xmlns:Helper="clr-namespace:DataMaster_PLC.Helpers"

 <!-- Password Input -->
 <StackPanel Orientation="Horizontal" Margin="0,0,0,10">
     <materialDesign:PackIcon Kind="KeyVariant" VerticalAlignment="Center" Margin="0,0,5,0"/>
     <PasswordBox Width="230"
                  Helper:PasswordBoxHelper.Attach="True"
                  Helper:PasswordBoxHelper.Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  materialDesign:HintAssist.Hint="Password"
                  Style="{StaticResource MaterialDesignPasswordBox}"/>
 </StackPanel>

PasswordHelper.cs

using System.Windows;
using System.Windows.Controls;

namespace DataMaster_PLC.Helpers {
    /// <summary>
    /// 提供一个辅助工具,用于使PasswordBox的Password属性能够进行数据绑定。
    /// </summary>
    public class PasswordBoxHelper {
        /// <summary>
        /// 注册附加依赖属性"Password",类型为string,当其值改变时触发OnPasswordPropertyChanged方法
        /// </summary>
        public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached(
            "Password", 
            typeof(string), 
            typeof(PasswordBoxHelper), 
            new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));

        /// <summary>
        /// 注册附加依赖属性"Attach",表示是否需要启用密码绑定功能,当其值改变时触发Attach方法
        /// </summary>
        public static readonly DependencyProperty AttachProperty = DependencyProperty.RegisterAttached(
            "Attach", 
            typeof(bool), 
            typeof(PasswordBoxHelper), 
            new PropertyMetadata(false, Attach));

        /// <summary>
        /// 私有静态依赖属性"IsUpdating",用于跟踪PasswordBox密码更新状态
        /// </summary>
        private static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached(
            "IsUpdating", 
            typeof(bool), typeof(PasswordBoxHelper));

        /// <summary>
        /// 设置附加属性"Attach"的值
        /// </summary>
        public static void SetAttach(DependencyObject dp, bool value) {
            dp.SetValue(AttachProperty, value);
        }

        /// <summary>
        /// 取附加属性"Attach"的值
        /// </summary>
        public static bool GetAttach(DependencyObject dp) {
            return (bool)dp.GetValue(AttachProperty);
        }

        /// <summary>
        /// 获取附加属性"Password"的值
        /// </summary>
        public static string GetPassword(DependencyObject dp) {
            return (string)dp.GetValue(PasswordProperty);
        }

        /// <summary>
        /// 置附加属性"Password"的值
        /// </summary>
        public static void SetPassword(DependencyObject dp, string value) {
            dp.SetValue(PasswordProperty, value);
        }

        /// <summary>
        /// 获取附加属性"IsUpdating"的值
        /// </summary>
        private static bool GetIsUpdating(DependencyObject dp) {
            return (bool)dp.GetValue(IsUpdatingProperty);
        }

        /// <summary>
        /// 设置附加属性"IsUpdating"的值
        /// </summary>
        private static void SetIsUpdating(DependencyObject dp, bool value) {
            dp.SetValue(IsUpdatingProperty, value);
        }

        /// <summary>
        /// 当"Password"属性发生变化时调用此方法,同步PasswordBox的实际密码与绑定值
        /// </summary>
        private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
            if (sender is PasswordBox passwordBox) {
                passwordBox.PasswordChanged -= PasswordChanged;

                // 防止在更新过程中引发无限循环
                if (!(bool)GetIsUpdating(passwordBox)) {
                    passwordBox.Password = (string)e.NewValue;
                }
                passwordBox.PasswordChanged += PasswordChanged;
            }
        }

        /// <summary>
        /// 当"Attach"属性值变化时(即绑定或解绑事件处理程序)调用此方法
        /// </summary>
        private static void Attach(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
            if (sender is not PasswordBox passwordBox)
                return;
            if ((bool)e.OldValue) {
                passwordBox.PasswordChanged -= PasswordChanged;
            }
            if ((bool)e.NewValue) {
                passwordBox.PasswordChanged += PasswordChanged;
            }
        }

        /// <summary>
        /// 密码更改事件处理程序,当PasswordBox的密码发生更改时,更新绑定到Password属性的值
        /// </summary>
        private static void PasswordChanged(object sender, RoutedEventArgs e) {
            if (sender is PasswordBox passwordBox) {
                SetIsUpdating(passwordBox, true);
                SetPassword(passwordBox, passwordBox.Password);
                SetIsUpdating(passwordBox, false);
            }
        }
    }
}

LoginViewModel.cs

 private string _password = string.Empty;
/// <summary>
/// 密码属性
/// </summary>
public string Password {
    get => _password;
    set {
        _password = value;
        OnPropertyChanged(nameof(Password));
    }
}


THE END


分享
赞赏
精选留言 写留言