关闭

WPF 绑定密码

标签: wpf绑定密码mvvm
1283人阅读 评论(0) 收藏 举报
分类:

我们发现我们无法绑定密码框的密码,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

还有一个简单方法

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;
        }
    }
}

原文:http://lindexi.oschina.io/lindexi/post/WPF-%E7%BB%91%E5%AE%9A%E5%AF%86%E7%A0%81/

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

1
0
查看评论

WPF密码控件PasswordBox之 MVVM绑定使用

1、添加 控件 密码输入控件:如下 所示 : 重点是 InputMethod.PreferredImeConversionMode="NoConversion" 标识 2、定义所在父级窗体 名称 如 WIN 3、添加按钮 及按钮 命令 &...
  • layfly1297
  • layfly1297
  • 2017-06-30 16:06
  • 799

WPF PasswordBox.Password 的数据绑定

WPF的PasswordBox控件的Password属性不是依赖属性,无法直接进行数据绑定,为使其在MVVM模式中正常使用,可以为PasswordBox增加一个助手类,代码如下: 注:代码摘自:http://www.wpftutorial.net/PasswordBox.html [...
  • ryb666666
  • ryb666666
  • 2012-06-04 10:39
  • 4235

PasswordBox 实现数据绑定

1.重新定义一个PasswordHelper类 PasswordBoxHelper.cs /// <summary> /// Password 绑定功能 /// </summary> public static class PasswordBoxHe...
  • qq_32493189
  • qq_32493189
  • 2016-12-04 21:11
  • 813

WPF中设置PasswordBox为空,背景为文字提示

继上篇博客textbox为空时,背景为文字提示,关于密码框水印就不同于文本框了,可以写个Brush就搞定,因为密码框是没有可以用于判断输入非空的依赖属性的,     下面就说一下实现过程     1、新建一个类:PasswordBoxHel...
  • kwy15732621629
  • kwy15732621629
  • 2016-06-25 15:53
  • 3718

WPF教程(二十)密码框

WPF中编辑常规的文字都是使用文本框,但是如果是输入密码呢?功能应该是一样的,但是我们不想周边的人看着我们一个字母一个字母的输入,这样密码就被泄漏了,因此我们想用别的字符来替代真实密码的显示。出于这个目的,WPF有一个密码框控件,用起来和文本框一样。 <Window x:Class=&quo...
  • seanbei
  • seanbei
  • 2016-10-19 22:51
  • 4473

如何绑定PasswordBox控制中的Password属性

如何绑定PasswordBox控制中的Password属性
  • shaosheng2008
  • shaosheng2008
  • 2015-11-08 18:19
  • 597

MVVM 绑定 PasswordBox

  • 2017-08-31 20:47
  • 239KB
  • 下载

潘鹏整理WPF(7)文本控件TextBox&&PassWordBox

TextBox换行属性TextWrapping默认是NoWrap Wrap WrapWithOverflow 这个有可能造出溢出的情况,所以一般用Wrap选择文本选择上面TextBox中的文本,在下面的TextBlock中出现你选择是 从第几个字符开始、 选择了多少个字符, 择的...
  • PanPen120
  • PanPen120
  • 2015-09-22 00:56
  • 1087

PasswordBox

  • 2013-06-06 15:02
  • 2.58MB
  • 下载

[WPF]实现密码框的密码绑定

                         ...
  • zhouyinhui
  • zhouyinhui
  • 2009-08-27 11:44
  • 1613
    个人资料
    • 访问:624267次
    • 积分:9163
    • 等级:
    • 排名:第2410名
    • 原创:240篇
    • 转载:16篇
    • 译文:25篇
    • 评论:240条
    博客专栏
    文章分类
    最新评论