`
lindexi-gd
  • 浏览: 139543 次
社区版块
存档分类
最新评论

WPF 绑定密码

 
阅读更多

我们发现我们无法绑定密码框的密码,PasswordBox 的 Password 不能绑定。

我们想做 MVVM ,我们需要绑定密码,不能使用前台 xaml.cs 监听 密码改变得到密码的值,传到 ViewModel 。

本文提供一个简单方法来绑定 WPF 的 PasswordBox 的 Password 。这种方法不仅在 WPF 可以使用,在 UWP 也可以使用。关于 UWP 绑定密码,可以在我博客 win10 uwp 绑定密码 查看。

<!--more-->

我在网上找的很多大神给出的可以解决绑定密码的方法,下面是我找的一个简单方法。

首先需要新建一个类 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 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
分享到:
评论

相关推荐

    WPF密码明文显示样式.zip

    在Windows Presentation Foundation(WPF)框架中,设计用户界面时,我们经常遇到处理密码输入的情况。"WPF密码明文显示样式.zip" 提供了一个示例,它涉及到如何在WPF应用中创建一个既能以星号(*)或圆点(•)隐藏...

    WPF文本框密码框水印.rar

    在Windows Presentation Foundation (WPF) 中,开发人员经常需要实现一些高级UI功能,如文本框(TextBox)的水印效果、密码框(PasswordBox)以及它们的自定义样式。"WPF文本框密码框水印.rar" 文件可能包含了一个...

    用Wpf编写的验证用户名和密码

    在本文中,我们将深入探讨如何使用WPF(Windows Presentation Foundation)来实现一个验证用户名和密码的界面。WPF是.NET Framework的一部分,它提供了一个强大的工具集来构建丰富的、交互式的桌面应用程序。对于...

    C#-WPF-密码生成Tool

    在本文中,我们将深入探讨如何使用C#编程语言与Windows Presentation Foundation(WPF)框架创建一个密码生成工具。这个工具的目的是为特定的"Application Name"生成安全的、随机的密码。通过理解以下知识点,你可以...

    wpf 带水印的passwordbox控件

    在Windows Presentation Foundation (WPF) 中,`PasswordBox` 是一个常见的控件,用于收集用户的密码输入,确保数据的安全性。然而,原生的`PasswordBox` 控件并不支持水印功能,即在用户未输入任何字符时显示提示性...

    C#WPF登陆DEMO

    4. **数据绑定**:WPF中的数据绑定机制使得视图(UI)和模型(业务逻辑)可以自动保持同步。在这个DEMO中,可能使用数据绑定将文本框的值绑定到后台的属性,以便于获取和验证用户的输入。 5. **密码可见性切换**:...

    WPF PasswordBox和属性双向绑定

    在Windows Presentation Foundation (WPF) 中,PasswordBox控件是一个常用元素,用于处理用户的敏感信息,如密码输入。本文将深入探讨如何实现PasswordBox与属性的双向绑定,以确保数据的实时更新和安全处理。 首先...

    WPF实例,使用MVVM框架实现登录,对于密码文本框没有绑定属性,增加附加属性实现双向绑定,布局使用简单动画,使用字体图标

    在本WPF实例中,我们将深入探讨如何利用MVVM(Model-View-ViewModel)框架构建一个登录界面,同时实现密码文本框的双向绑定以及添加简单的布局动画和字体图标。这是一次将现代UI设计原则与实用功能相结合的实践,...

    WPF MVVM完整示例(登录窗口)

    3. **PasswordBox的绑定**:在MVVM中,PasswordBox控件的密码通常不直接绑定,因为它的密码属性不支持双向绑定。可以使用`PasswordBox.PasswordChanged`事件和一个辅助属性来实现密码的更新。 4. **RadioButton绑定...

    WPF 管理系统源码分享.7z

    WPF是微软.NET Framework的一部分,用于构建桌面应用程序,它提供了丰富的用户体验和强大的数据绑定功能。 【描述】中的".7z"表明这个源码是用7-Zip这种高效压缩工具打包的,通常7-Zip能提供更高的压缩比,方便用户...

    WPF登录和跳转程序

    WPF是微软推出的一种用于构建桌面应用的UI框架,它提供了丰富的图形效果、数据绑定、事件处理等特性,使得开发者能够创建出美观且功能强大的用户界面。 在WPF登录程序中,核心知识点主要包括以下几个方面: 1. **...

    WPF动态登录界面设计

    总的来说,创建一个动态的WPF登录界面涉及到了XAML布局、数据绑定、事件处理、动画效果以及安全性考虑等多个方面。熟练掌握这些技能,将使你能够构建出更加吸引人的、具有高度交互性的用户界面。

    WPF登录打开WinForm主界面

    同时,可以考虑使用数据绑定和MVVM(Model-View-ViewModel)模式来提高代码的可维护性和可测试性。 标签"WPF,Winform"表明这个项目结合了这两种技术,虽然它们分别代表了不同的UI设计范式,但可以通过适当的交互和...

    一个非常好看登录界面,用WPF完成的

    WPF是.NET Framework的一部分,是一个用于创建桌面应用程序的强大工具,它提供了丰富的图形层、数据绑定、样式和模板等特性,使得开发者能够创建出具有高度交互性和视觉吸引力的应用。 WPF的核心概念之一是XAML...

    WPF 登录界面

    4. **数据绑定**: 数据绑定是WPF的核心特性之一,它使得UI与后台数据模型之间能自动同步。在登录界面中,文本框的内容可能与视图模型中的相应属性进行双向绑定,这样当用户输入时,模型中的数据也会实时更新。 5. *...

    WPF MVVM实现简易登录,页面跳转等功能

    例如,我们可以用`&lt;TextBox&gt;`控件绑定到用户名和密码属性,`&lt;Button&gt;`控件的`Command`属性绑定到登录命令。 一旦用户点击登录按钮,ViewModel中的登录命令会被触发,执行验证逻辑。这可能涉及到与数据库或API的交互...

    WPF操作Redis简单实例

    6. **WPF UI集成**:在WPF应用中,可以通过数据绑定显示Redis数据,使用`INotifyPropertyChanged`接口确保UI实时更新。此外,可以创建命令(Command)来处理Redis的读写操作。 7. **性能优化**:了解连接池的概念,...

    wpf视频-百度云链接.zip

    3. **数据绑定**:WPF的数据绑定机制使得UI与业务逻辑之间的数据交互变得简单,实现了视图和模型的解耦。它可以将控件的属性自动绑定到数据源,实现双向数据同步。 4. **样式与模板**:通过样式和控件模板,开发者...

Global site tag (gtag.js) - Google Analytics