您的位置:首页 > 博客中心 > 数据库 >

在MVVM中使用PasswordBox控件

时间:2022-03-14 04:14

在MVVM中使用PasswordBox控件,碰到一个问题。由于**PasswordBox.Password**属性并不是一个依赖属性,所以无法将其作为Binding的目标。# 使用附加属性的解决方案![Password Demo.gif](http://upload-images.jianshu.io/upload_images/140233-dbd415eb4cf9aeb2.gif)**思路:**定义两个依赖属性**Attach**和**AttachPassoword**Attatch为True时,给PasswordBox的PasswordChanged事件添加一个订阅者。在这个订阅者中,利用AttachPassword的Set包装器将PasswordBox.Password赋值给这个附加属性。然后在XAML中,使用扩展标记将AttachPassword作为绑定的目标。**数据流:**PasswordBox.Password->AttachedPasswordProperty<->TextBlock.TextProperty;可以发现,这里缺少了一个环节,就是PasswordBox.Password<-AttachedPasswordProperty,这个可以在AttachedPasswordProperty的回调方法中实现。这里注意增加验证机制,既代码中的isUpdating;如果不加这个验证,就会发生环形数据流(严格来说是以PasswordBox.Password为目标的逻辑上的MulitBinnd)!!会导致光标位置出现问题。```csharpusing System.Windows;using System.Windows.Controls;
namespace 密码绑定{    public static class PasswordHelper    {        private static bool isUpdating = false;
        public static readonly DependencyProperty AttachPasswordProperty =            DependencyProperty.RegisterAttached("AttachPassword", typeof(string), typeof(PasswordHelper), new PropertyMetadata(string.Empty, OnAttachPasswordPropertyChanged));        public static string GetAttachPassword(DependencyObject obj)        {            return (string)obj.GetValue(AttachPasswordProperty);        }        public static void SetAttachPassword(DependencyObject obj, string value)        {            obj.SetValue(AttachPasswordProperty, value);        }
        public static readonly DependencyProperty AttachProperty =            DependencyProperty.RegisterAttached("Attach", typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, OnAttachPropertyChanged));
        public static bool GetAttach(DependencyObject obj)        {            return (bool)obj.GetValue(AttachProperty);        }        public static void SetAttach(DependencyObject obj, bool value)        {            obj.SetValue(AttachProperty, value);        }
        private static void OnAttachPropertyChanged(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 OnAttachPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)        {            if (!isUpdating)            {                PasswordBox passwordBox = sender as PasswordBox;                if (passwordBox == null)                    return;
                passwordBox.Password = (string)e.NewValue;            }        }
        private static void PasswordChanged(object sender, RoutedEventArgs e)        {            PasswordBox passwordBox = sender as PasswordBox;            isUpdating = true;            SetAttachPassword(passwordBox, passwordBox.Password);            isUpdating = false;        }    }}`````` <PasswordBox Grid.Column="1"  Margin="5"             loc:PasswordHelper.Attach="True"             loc:PasswordHelper.AttachPassword="{Binding Text, ElementName=plain, Mode=TwoWay}" >            </PasswordBox><TextBlock Name="plain" Grid.Row="1" Grid.Column="1"  Margin="5"></TextBlock><Button ...></Button>```# 风险PasswordBox.Password不依赖化的缘由我想是出于安全性的考虑,而View与ViewModel之间通过DataBinding进行驱动必定能发现端倪。
![snoop.png](http://upload-images.jianshu.io/upload_images/140233-fe479aa7a42370e6.png)(看图不说话)
是否采用这种方案,主要的矛盾源头还是安全性和MVVM~




热门排行

今日推荐

热门手游