2009-07-08 16 views
16

こんにちは。 MVVMで作業しています。私はを持っています。ViewModelプロパティパスワードを持つUserViewModelを呼び出します。 には、PasswordBoxコントロールがあります。MVVMを使ったPasswordBox

<PasswordBox x:Name="txtPassword" Password="{Binding Password}" /> 

しかし、このxamlは機能しません。どのようにバインディングを行うのですか?助けてください!!

+0

ウィンドウのdatacontextがビューモデルに設定されていることを確認しましたか。問題を理解できるように、コードをいくつか追加する必要があります。 –

+0

DataContextこれは問題ありません。他のプロパティは正常に動作しますが、PasswordBoxではできません。 – Rangel

答えて

13

セキュリティ上の理由から、Passwordプロパティは依存関係プロパティではないため、バインドできません。残念ながら、あなたは私クイック検索がどのように示しているthis blog postに私をもたらします(OnPropertyChangedをイベントに登録して、コードを通じて値を更新...)昔ながらの方法の背後にあるコードで


結合を実行する必要があります問題を回避するために添付プロパティを記述します。これが本当に価値があるかどうかは、コードビハインドへのあなたの嫌悪に本当に左右されます。

5

パスワードをラップするコントロールを作成し、Passwordプロパティの依存関係プロパティを追加できます。

public class BindablePasswordBox : Decorator 
{ 
    public static readonly DependencyProperty PasswordProperty = 
     DependencyProperty.Register("Password", typeof(string), typeof(BindablePasswordBox)); 

    public string Password 
    { 
     get { return (string)GetValue(PasswordProperty); } 
     set { SetValue(PasswordProperty, value); } 
    } 

    public BindablePasswordBox() 
    { 
     Child = new PasswordBox(); 
     ((PasswordBox)Child).PasswordChanged += BindablePasswordBox_PasswordChanged; 
    } 

    void BindablePasswordBox_PasswordChanged(object sender, RoutedEventArgs e) 
    { 
     Password = ((PasswordBox)Child).Password; 
    } 

} 
+0

私は同様のソリューションを使用しますが、DependencyPropertyをFrameworkPropertyMetadata.BindsTwoWayByDefaultに登録すると便利です。そのたびにXAMLで宣言する必要はありません。 –

+0

私はこれがかなり古いことを理解していますが、このメソッドを使用すると、FontSizeとContentAlignmentを設定する機能が削除されます。これをどうやって回避するのですか? –

0

チェックパスワードボックスに別のスレッド:あなたはあなたのような何かを行うことができなければならない場合

私はちょうど背後にあるコードを使用するだろうが。 DPまたはパブリックプロパティにパスワードを保持しない方が良い。

Other thread on passwordbox

2

BindablePasswordBoxとの問題があります。これは、PasswordBoxからPasswordPropertyへの一方向でのみ機能します。以下は両方向で動作する修正版です。 PropertyChangedCallbackを登録し、呼び出されたときにPasswordBoxのパスワードを更新します。 誰かがこの点を知りたがっていれば幸いです。

public class BindablePasswordBox : Decorator 
{ 
    public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register("Password", typeof(string), typeof(BindablePasswordBox), new PropertyMetadata(string.Empty, OnDependencyPropertyChanged)); 
    public string Password 
    { 
     get { return (string)GetValue(PasswordProperty); } 
     set { SetValue(PasswordProperty, value); } 
    } 

    private static void OnDependencyPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     BindablePasswordBox p = source as BindablePasswordBox; 
     if (p != null) 
     { 
      if (e.Property == PasswordProperty) 
      { 
       var pb = p.Child as PasswordBox; 
       if (pb != null) 
       { 
        if (pb.Password != p.Password) 
         pb.Password = p.Password; 
       } 
      } 
     } 
    } 

    public BindablePasswordBox() 
    { 
     Child = new PasswordBox(); 
     ((PasswordBox)Child).PasswordChanged += BindablePasswordBox_PasswordChanged; 
    } 

    void BindablePasswordBox_PasswordChanged(object sender, RoutedEventArgs e) 
    { 
     Password = ((PasswordBox)Child).Password; 
    } 
} 
1

いずれかの時点でプレーンテキストとしてメモリ内で利用できるパスワードを避けるために、私は私のコマンドのパラメータとして価値を提供します。

<Label>User Name</Label> 
<TextBox Text="{Binding UserName}" /> 
<Label>Password</Label> 
<PasswordBox Name="PasswordBox" /> 
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0 16 0 0"> 
    <Button Margin="0 0 8 0" MinWidth="65" 
      Command="{Binding LoginAccept}" 
      CommandParameter="{Binding ElementName=PasswordBox}"> 
     Login 
    </Button> 
    <Button MinWidth="65" Command="{Binding LoginCancel}">Cancel</Button> 
</StackPanel> 

次に、私のビューモデルです。

public DelegateCommand<object> LoginAccept { get; private set; } 
public DelegateCommand<object> LoginCancel { get; private set; } 

public LoginViewModel { 
    LoginAccept = new DelegateCommand<object>(o => OnLogin(o), (o) => IsLoginVisible); 
    LoginCancel = new DelegateCommand<object>(o => OnLoginCancel(), (o) => IsLoginVisible); 
} 

private void OnLogin(object o) 
{ 
    var passwordBox = (o as System.Windows.Controls.PasswordBox); 
    var password = passwordBox.SecurePassword.Copy(); 
    passwordBox.Clear(); 
    ShowLogin = false; 
    var credential = new System.Net.NetworkCredential(UserName, password); 
} 

private void OnLoginCancel() 
{ 
    ShowLogin = false; 
} 

SecurePasswordをバインディングから直接提供することは意味がありますが、常に空の値を提供するようです。これはうまくいかない:

<Button Margin="0 0 8 0" MinWidth="65" 
      Command="{Binding LoginAccept}" 
      CommandParameter="{Binding ElementName=PasswordBox, Path=SecurePassword}"> 
+0

私はまったく同じことを経験しました!なぜあなたは 'バインディングから直接SecurePassword'が動作していないのか知っていますか? – Athafoud

+1

その特定のタイプには意図的な制限があります。SecurePasswordはDependencyPropertyではない可能性がありますが、問題には寄与しますが、標準の読み取り専用プロパティです。しかし、コントロール全体を渡すのではなく、それがパラメータとして渡すことができると思います。 –

関連する問題