2009-05-20 15 views
10

M-V-VMとWPFを使い始めたばかりで、いくつかのバインディングの問題を理解する上で問題があります。PasswordBox Binding

ComboBoxPasswordBoxのログインページがあります。 ComboBoxは次のようになります。

<ComboBox Name="comboBox1" SelectedItem="{Binding Path=Username}"> 

これは正常に動作します - 私の値は毎回ComboBoxSelectedItemの変更を更新しましょう!

public bool CanLogin() 
{ 
    return !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password); 
} 

だから私の問題は、私はViewModelににパスワードプロパティにバインドPasswordBoxを持っていないです。私のViewModelで

私は、ログインボタンがアクティブになっている場合は、このメソッドを使用していますICommandを決定する必要があります - 私はそれがいつ更新されるかを伝える方法がありません。

PasswordBoxの値を自分のViewModelにどうやって取得できますか?私が読んだことのすべては、セキュリティ上の理由からPasswordBoxを束縛しないと言います。 CanLogin()のパスワード制限を解除するだけで、AccountServiceに渡すための値が必要です。

+0

パスワードを文字列(SecureStringではなく)としてバインドすると、プロセスのメモリにパスワードが公開されます。 どちらのソリューションもセキュリティを妥協する – Rubinsh

答えて

27

興味深い。

このブログの記事を見て、あなたを助けているかどうかを確認してください。 http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html

どうやらリンクはので、ここで今死んでいる元の溶液は、(hereを発見した)である:

あなたはこのようなヘルパーを作成するために、添付プロパティを使用することができます。

 
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; 
     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; 
     SetIsUpdating(passwordBox, true); 
     SetPassword(passwordBox, passwordBox.Password); 
     SetIsUpdating(passwordBox, false); 
    } 
} 

それを使用します。

<PasswordBox w:PasswordHelper.Attach="True" 
      w:PasswordHelper.Password="{Binding Text, ElementName=plain, Mode=TwoWay}" 
      Width="100"/> 
+0

私はこれが本当に古い答えで、動作していることを知っていますが、誰かがコードがどのような不具合に気付いていましたか?たぶん、それほど複雑ではないバージョンを投稿するべきでしょうか? –

+1

上記のコードは機能しません(PasswordHelper)。代わりにリンクのメソッド(PasswordBoxAssistant)を使用してください。 http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html – morph85

8

私はバインド可能なパスワードボックスであるGIST hereを投稿しました。

+1

良い解決策。埋め込まれたPasswordBoxのプロパティ(例:前景、背景)をXAMLで簡単にアクセスできるようにするためのヒント –