WPF 繫結密碼
我們發現我們無法繫結密碼框的密碼,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。
還有一個簡單方法
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;
}
}
}
相關推薦
WPF 繫結密碼
我們發現我們無法繫結密碼框的密碼,PasswordBox 的 Password 不能繫結。 我們想做 MVVM ,我們需要繫結密碼,不能使用前臺 xaml.cs 監聽 密碼改變得到密碼的值,傳到 ViewModel 。 本文提供一個簡單方法來繫結 WPF 的
WPF--繫結自定義資料型別
WPF作為資料繫結的目標: 使用DataContext屬性,表示當前控制元件中的每個元素都繫結此資料: 資料型別定義: public class FamilyData { private string m_familyName; private string m_widt
WPF繫結兩個ComboBox互相響應對方的選擇不成功請求幫助
windows2008無法執行.netremoting服務程式在XP,win2003下一切正常如何為ListView的每一ListViewItem新增MouseMove事件windows2008無法執行.netremoting服務程式在XP,win2003下一切正常如何為Li
wpf繫結全域性靜態變數(mvvm)
原文 wpf繫結全域性靜態變數(mvvm) 在實際的開發中,有一些集合或者屬性可能是全域性的,比如當你做一個oa的時候,可能需要展示所有的人員,這時這個所有的人員列表顯然可以作為全域性引數,比如這裡有一個全域性的靜態屬性UserList。而你在使用mvvm做wpf開發的時候,一般每個view都已經
LibVLC.NET 與WPF繫結播放器
先決條件LibVLC.NET提供.NET繫結到VLC媒體播放器的LibVLC核心庫(libVLC)。由於使用了一些更新的LibVLC功能,LibVLC.NET需要VLC版本1.2,可以在這裡下載。如果您已將VLC媒體播放器(1.2)安裝在其預設位置(例如C:\ Program
WPF繫結之索引器值變化通知
原文: WPF繫結之索引器值變化通知 背景 在某些應用中,需要在介面上繫結到索引器,並在值發生變化時實時更新。 解決方案 只要將包含索引器的類實現INotifyPropertyChanged介面,並在索引值更改時引發PropertyChanged事件,並將屬性名稱設定為Item[]即可。示例程式碼如下
WPF繫結模式
<Window x:Class="WPF_Started.Controls.DataBinding.BindingMode" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x
WPF繫結不到父控制元件屬性
原因: 如果A控制元件並不是屬於visual tree的部分,那麼他不能連線到他父控制元件的datacontext,也就不能繫結到父控制元件的屬性 解決方案: 使用一個Freezable做代理 public class BindingProx
WPF繫結概念基礎(四大組成,繫結方向,繫結觸發)
本文為原創文章,可以轉載但不得商用,轉載必須註明來源。 今天講述的是一個關於WPF繫結的小例子,學習好WPF繫結,幾乎可以達到邏輯和介面完全隔離的神奇效果。 關於邏輯和介面是否可以完全可以隔離,我想告訴大家的是,如果學好了繫結機制和內部執行原理,是可以達到
wpf 繫結表示式和手動更新源
<Window x:Class="BindingExpressionExam.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmln
菜鳥做wpf繫結xml使遇到很多問題,跪求解
跪求各位高手,菜鳥在做wpf繫結xml操作,遇到以下難題,求各位高手:wpf 繫結 xml 為資料來源的圖片繫結(及佈局)方法,單擊按鈕改變屬性:如下圖單擊Button,改變ID、Name、Age、Sex中的任何一個或幾個屬性值,急求,謝謝
WPF -- 繫結顯示多個屬性
參考: 方法1: DataTemplate 包含一個 StackPanel; StackPanel 包含多個 TextBlock; 一個屬性繫結到一個 TextBlock。 (我比較喜歡的) XAML程式碼 <ItemsControl ItemsSource="{Binding Path=.}"&
WPF繫結入門
一 概述 文章一開始,將給出一個使用WPF繫結的小例項。並以此為起點,逐步展開對WPF繫結知識的探討。 二 例項演示 1新建WPF應用程式WpfBindingExp,下面是程式主畫面的程式碼。 <pre name="code" class="html">&l
WPF繫結資料來源之RelativeSource
一.FindAncestor 有時候我們不確定作為資料來源的物件叫什麼名字,但知道作為繫結源與UI佈局有相對的關係,如下是一段XAML程式碼,說明多層佈局控制元件中放置一個文字控制元件,來顯示父級控制元件的名稱。 1、XAML Html程式碼: <Grid x:Name="g1" Background
WPF 繫結中Converter的應用
在WPF 經常用到繫結,如果繫結的源資料和目標屬性是同類型的則不需要轉換。比如 <TextBox x:Name="txt1" Background="Blue" Text="測試"/> <TextBox Ba
WPF繫結失效問題(規避解決)
使用WPF繫結後臺資料,在多次切換資料後繫結失效 將一個後臺資料繫結到多個RadioButton的IsChecked上,通過自定義轉換將整型資料轉換成bool型資料。點選介面上的新增按鈕,在button事件中,將繫結的物件資料加1,然後再前臺顯示,在多次後,前
WPF繫結(Binding)繫結物件集合修改顯示屬性問題
問題描述:我打算選中列表中的欄位,用文字框的值替換選中的欄位。然而在使用Binging將存放自定義類(Student)的集合繫結到ListBox上,顯示的是這個類的“Name”屬性。在修改這個屬性後卻沒有看到列表中選中欄位的變化。ListBox取值繫結儲存Sutdent類的物
wpf 繫結資料無法更新ui控制元件可能存在的問題
BindingMode的列舉值有: ① OneWay ② TwoWay ③ OneTime:根據源端屬性值設定目標屬性值,之後的改變會被忽略,除非呼叫BindingExpression.UpdateTarge方法 ④ OneWayToSource:與OneWay類似,
WPF繫結到linq表示式
using ClassLibrary;using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Linq;using System.Text;
wpf MVVM passwordbox密碼框繫結問題簡單解決辦法
網上關於這個方案的解決辦法都比較複雜,所以才來寫這篇部落格提供一種簡單方法。 本來沒有在意這個問題,直到突然有一個發現passwordbox為了安全性把password屬性做成了非依賴屬性,不能進行繫結也不能進行屬性值變化監聽,網上搜了一些資料發現解決辦法都比