在MVVM中使用PasswordBox控件

在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)!!会导致光标位置出现问题。

```csharp

using 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~

来自为知笔记(Wiz)

时间: 2024-10-06 19:58:41

在MVVM中使用PasswordBox控件的相关文章

WPF中PasswordBox控件的Password属性的数据绑定

原文:WPF中PasswordBox控件的Password属性的数据绑定 英文原文:http://www.wpftutorial.net/PasswordBox.html 中文原文:http://blog.csdn.net/oyi319/article/details/6551532 WPF的PasswordBox控件的Password属性不是依赖属性,无法直接进行数据绑定,为使其在MVVM模式中正常使用,可以为PasswordBox增加一个助手类,代码如下: 注:代码摘自:http://www

结合ItemsControl在Canvas中动态添加控件的最MVVM的方式

今天很开心的收获: ItemsControl 中 ItemsPanel的重定义和 ItemContainerStyle 以及 ItemTemplate 三者的巧妙结合,在后台代码不实例化任何控件的前提下,实现标准的MVVM模式下,在前台Canvas中动态创建包含各种数据展示形态的控件. 好东西要共享,先上简化过的XAML最终解决方案: <UserControl.Resources> <Style x:Key="MyItemsControlStyle" TargetTy

android 在布局中动态添加控件

第一步 Java代码 final LayoutInflater inflater = LayoutInflater.from(this); 第二步:获取需要被添加控件的布局 Java代码 final LinearLayout lin = (LinearLayout) findViewById(R.id.LinearLayout01); 第三步:获取需要添加的布局(控件) Java代码 LinearLayout layout = (LinearLayout) inflater.inflate( R

使用Devexpress中的CharControl控件,需要控制AxisY轴的显示范围,需要使用该控件的BoundDataChanged事件

一.控制ChartControl的Y轴范围 使用Devexpress中的CharControl控件,需要控制AxisY轴的显示范围,需要使用该控件的BoundDataChanged事件,具体代码如下: 该代码实现的效果如下: 参考文献: [1]AxisY Range Auto https://www.devexpress.com/Support/Center/Question/Details/Q266328 二.设置GridControl表格中的超级链接: 1.首先在表格的设计器中添加一个Hyp

C# dataGridView控件中加入comboBox控件及注意事项

DataGridViewComboBoxColumn pCombo; private void Teaching_Add_Load(object sender, EventArgs e) { MyDBase DB = new MyDBase(DBUser.sserver,DBUser.DBName, DBUser.suser, DBUser.spasswd); DataSet DS= DB.GetRecordset("select * from view_teach_tmp"); da

WPF 中动态改变控件模板

在某些项目中,可能需要动态的改变控件的模板,例如软件中可以选择不同的主题,在不同的主题下软件界面.控件的样式都会有所不同,这时即可通过改变控件模板的方式实现期望的功能. 基本方法是当用户点击切换主题按钮是加载新的资源字典,并使用新加载的资源字典替代当前的资源字典这时要用到ResourceManager. 假设现有两个不同的资源字典文件Dictionary1.xaml和Dictionary2.xaml存在于Themes文件夹内: 在MainPage中使用其中一个资源字典作为默认样式文件: <Win

FormView的插入模板中的DropDownList控件参数

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DT

SplendidCRM中给来自EditView中的listbox控件设置选中值或数据源

DropDownList list = this.findContol("aas") as DropDownList;list.DataSource = new DataTable() ------------------------------- Control ctl = this.FindControl("NAME");            if (ctl != null)            {                if (ctl is Dro

vs2010中的ADO控件及绑定控件

要在项目中添加某一个ActiveX控件,则该ActiveX控件必须要注册.由于VS2010中,并没有自动注册ADO及ADO数据绑定控件(Microsoft ADO Data Control,Microsoft DataCombo等),参考http://msdn.microsoft.com/zh-cn/library/dsb06ab6(v=vs.100).aspx 故没法在插入ActiveX控件对话框中找到它们. 若要在VS2010中获得这种控件,需要另外下载然后注册,或者利用以前的VS版本获得.