• 2018-2-13-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;
            }
        }
    }
    
  • 相关阅读:
    asp.net实现页面的一般处理程序(CGI)学习笔记
    .NET下的状态(State)模式 行为型模式
    (插件Plugin)AssemblyLoader解决方案(插件开发)
    SQL基础编写基本的SQL SELECT 语句
    在查询语句中使用NOLOCK和READPAST(ZT)
    C# 3.0语言增强学习笔记(一)
    ram,rom,flash
    自动激活你的ActiveX控件
    用C#编写ActiveX控件(二)
    用C#编写ActiveX控件(一)
  • 原文地址:https://www.cnblogs.com/lindexi/p/12085573.html
Copyright © 2020-2023  润新知