win10 uwp 绑定密码

win10 下,密码框无法绑定到ViewModel,Password是不可以绑定。

我们可以自己使用简单方法去绑定

我们之前在WPF 使用绑定密码框,我写了一篇,关于如何绑定,我提供一个我自己试了可以的类。

首先,我们新建一个类,这个类是让 PasswordBox 可以绑定Password。

UWP让 PasswordBox 可以绑定Password 的一个方法,其实我使用的和之前一样。

我们新建静态类,附件属性,只是和之前有的小不一样。

我们先写一个函数PasswordChanged这个函数是 Password 变化使用的,我们先判断sender 是不是 PasswordBox ,是的话我们就通知密码改变。

通知使用SetPassword(passwordBox, passwordBox.Password);我们要先更新password,然后更新界面,但是我们设置password,会自动更新界面,一旦界面更新又更新 password,这样不好,我们需要设置 Updateing,如果是 true,就是我们界面更新,直接更新 password 。如果是 false,那么是 password 更新界面。于是我们在 PasswordChanged ,修改依赖属性,必须添加是否后台修改密码 IsUpdating ,如果是后台添加就需要设置他为 true,目的是可以让前台修改通知,后台修改忽略,不然出现无限循环就不好。

                SetIsUpdating(passwordBox, true);
                SetPassword(passwordBox, passwordBox.Password);
                SetIsUpdating(passwordBox, false);

然后写private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)

这个函数是我们定义的一个属性变化时,判断 sender 是不是 PasswordBox ,是的话,因为我们绑定是双向,所以先把passwordBox.PasswordChanged -= PasswordChanged取消,然后判断是不是更新了,如果更新了,也就是完成更新if (!(bool)GetIsUpdating(passwordBox))我们就把新的Value给passwordBox.Password,不管有没更新,我们需要passwordBox.PasswordChanged += PasswordChanged

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

我们还需要一个Attach判断用户是不是要绑定,如果是 false ,就是和原来,不绑定

我们需要判断 sender 是 PasswordBox ,好像不是的话我们不需要做下,因为都是静态,使用事件绑定,用的是 sender ,关于 Sender 和 Origin 其实是不同的,不过在这里就使用 sender,不是路由事件。

我们判断,在使用 OldValue 是不是true,如果是的话,我们先把passwordBox.PasswordChanged -= PasswordChanged,不是的话不能passwordBox.PasswordChanged -= PasswordChanged ,因为之前不是已经添加了,所以不可以再移除,即使添加了,也不会出错。这样在修改密码就可以通过函数知道密码已经修改,通过已经修改的密码更新到附加属性,就可以让附加属性得到密码,绑定附加属性,就可以让vm得到值,于是这个核心就是这么简单。

判断NewValue,如果是true,passwordBox.PasswordChanged += PasswordChanged;,这时就是绑定了,以后修改了密码就可以知道了。

代码可以复制到一个文件,注意需要使用他所在的name,使用xmlns引用需要用到

    public static class PasswordBoxHelper
    {
        public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached(
            "Password", //属性
            typeof(string),//属性的类型
             typeof(PasswordBoxHelper), //属于的类,我们做的是静态,所以需要这个让附加属性可以知道他所在,我们到时可以使用 sender 拿到实例,所以需要知道他的类可以转
             new PropertyMetadata(default(string),//默认值
            OnPasswordPropertyChanged));//属性改变调的函数

        public static void SetPassword(DependencyObject element, string value)
        {
            element.SetValue(PasswordProperty, value);
        }

        public static string GetPassword(DependencyObject element)
        {
            return (string) element.GetValue(PasswordProperty);
        }

        public static readonly DependencyProperty AttachProperty = DependencyProperty.RegisterAttached(
            "Attach", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(default(bool),Attach));

        public static void SetAttach(DependencyObject element, bool value)
        {
            element.SetValue(AttachProperty, value);
        }

        public static bool GetAttach(DependencyObject element)
        {
            return (bool) element.GetValue(AttachProperty);
        }

        public static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached(
            "IsUpdating", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(default(bool)));

        public static void SetIsUpdating(DependencyObject element, bool value)
        {
            element.SetValue(IsUpdatingProperty, value);
        }

        public static bool GetIsUpdating(DependencyObject element)
        {
            return (bool) element.GetValue(IsUpdatingProperty);
        }

        private static void OnPasswordPropertyChanged(DependencyObject sender,
         DependencyPropertyChangedEventArgs e)
        {
            PasswordBox passwordBox = sender as PasswordBox;//sender就是实例
            if (passwordBox != null)
            {
                passwordBox.PasswordChanged -= PasswordChanged; //在WPF绑定密码有说为何这样做
                //我们需要修改的是在更改,所以不能让他继续 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;
            }
            //e.OldValue 改变前的值
            if ((bool)e.OldValue)//如果之前有绑定,我们就解绑
            {
                passwordBox.PasswordChanged -= PasswordChanged;
            }
            //e.NewValue 改变的值
            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);//设置我们修改的是UI绑定的修改,那么不更改PasswordBox.password
                //设置是false会修改,我们通知修改密码,然后他修改后台password又通知PasswordChanged 这样会炸
                SetPassword(passwordBox, passwordBox.Password);
                SetIsUpdating(passwordBox, false);
            }
        }
    }

我们的 ViewModel 有一个属性 password ,注意我们使用 Binding 把他绑定到 PasswordBox 的密码。绑定的过程

不需要去做修改,直接加上view:PasswordBoxHelper.Attach="True" view:PasswordBoxHelper.Password="{Binding Password,Mode=TwoWay}"

代码很简单,也就是把 不可绑定的 Password 改为下面的属性

 <PasswordBox  view:PasswordBoxHelper.Attach="True"
               view:PasswordBoxHelper.Password="{Binding Password,Mode=TwoWay}"
                 >

注意需要引用命名,好像属性比较长,但是我也没有好方法让他比较好看

附加属性使用的比较多,是不是需要我来写一个博客说下什么是附加属性。

对于 WPF 几乎和rt一样的 附加属性,如果没有找到 好的博客,直接去看 wpf就好啦,我在使用发现不需要去学新的东西就可以使用。

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

lindexi_gd CSDN认证博客专家 C# WPF UWP 微软最具价值专家
我是微软Windows应用开发方向的最具价值专家,欢迎访问我博客blog.lindexi.com里面有大量WPF和UWP博客
已标记关键词 清除标记
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质? 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹?   那么C++就是你个人能力提升,职业之路进阶的不二之选。 【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署; 2.吊打一切关于C++的笔试面试题; 3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。 【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块 基础篇 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 进阶篇 本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 提升篇: 本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页