2013-02-27 8 views
11

PasswordBoxの検証を試みています。妥当性確認を行うために、私はに続き、TextBoxの検証方法を示しています。PasswordBoxを検証する方法

問題はPasswordBoxesで発生します。 Passwordはセキュリティ上の理由でバインドできないため、this link(CodeProjectユーザーの場合はhereと記載されています)の後にバインディングを作成しようとしました。

だから、明らかに、素晴らしい! PasswordBoxをそのPasswordプロパティにバインドすることができます。したがって、私は自分のバリデーションにバインドできます。しかし、それは私を無視し...

これは私が使用する通常のTextBoxで、正常に動作します:

<local:ErrorProvider Grid.Column="1" Grid.Row="2" > 
    <TextBox Width="160" 
      HorizontalAlignment="Left" 
      Name="textBoxUserPass" 
      Text="{Binding Path=Password, UpdateSourceTrigger=Explicit}" /> 
</local:ErrorProvider> 

そして、これは私がシミュレートしようとしたPasswordBoxです:

<local:ErrorProvider Grid.Column="1" Grid.Row="2" > 
     <PasswordBox Width="160" 
      HorizontalAlignment="Left" 
      Name="textBoxUserPass" 
      local:PasswordBoxAssistant.BindPassword="True" 
      local:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, UpdateSourceTrigger=Explicit}" /> 
</local:ErrorProvider> 

これはどのようにありますそれぞれについてBindingExpressionを取得します。TextBox

BindingExpression beUserName = textBoxUserName.GetBindingExpression(TextBox.TextProperty); 
if (beUserName != null) beUserName.UpdateSource(); 

そして、これは私がPasswordBoxのためにそれを取得する方法である:

BindingExpression bePassword = textBoxUserPass.GetBindingExpression(PasswordBoxAssistant.BoundPassword); 
if (bePassword != null) bePassword.UpdateSource(); 

私たちはどんなミスをした場合は(私のバリデーションクラスで定義された)、私が行うとき、これは:

if (!beUserName.HasError && !bePassword.HasError) 

BindingExpressionを言う必要があります真エラーのバリデーションによって異なります。しかし、私のためにPasswordBoxは決して価値を得ることはできません...任意のアイデア?

+0

あなたは '設定しようとしたことがありあなたのバインディングでValidatesOnDataErrors = True'と 'ValidatesOnExceptions = True'ですか? –

+0

'PasswordBox'には存在しません... – Sonhja

+0

' BoundPassword'添付プロパティの場合は 'local:PasswordBoxAssistant.BoundPassword =" {Binding Path = Password、UpdateSourceTrigger = Explicit、ValidatesOnDataErrors = True、ValidatesOnExceptions = True} " –

答えて

11

ことはあなたの結合に対するValidatesOnDataErrors=TrueValidatesOnExceptions=Trueを設定してみてください

このようなMVVMオブジェクトを持っているとしましょう。WPF検証はを使用しています210:

このようなPasswordBoxと
public class MyObject : INotifyPropertyChanged, IDataErrorInfo 
{ 
    ... 
    public SecureString SecurePassword 
    { 
     get 
     { ... } 
     set 
     { 
      ... 
      OnPropertyChanged("SecurePassword"); 
     } 
    } 

    ... 

    string IDataErrorInfo.Error { get { return Validate(null); } } 
    string IDataErrorInfo.this[string columnName] { get { return Validate(columnName); } } 

    private string Validate(string memberName) 
    { 
     string error = null; 
     ... 
     if (memberName == "SecurePassword" || memberName == null) 
     { 
      // this is where I code my custom business rule 
      if (SecurePassword == null || SecurePassword.Length == 0) 
      { 
       error = "Password must be specified."; 
      } 
     } 
     ... 
     return error; 
    } 

} 

とウィンドウのXAML:

<PasswordBox Name="MyPassword" PasswordChanged="MyPassword_Changed" ... /> 

そこで、このような対応するウィンドウのコードが結合PasswordBoxをトリガします:

// add a custom DependencyProperty 
public static readonly DependencyProperty SecurePasswordProperty = 
    DependencyProperty.RegisterAttached("SecurePassword", typeof(SecureString), typeof(MyWindow)); 

public MyWindow() 
{ 
    InitializeComponent(); 

    DataContext = myObject; // created somewhere 

    // create a binding by code 
    Binding passwordBinding = new Binding(SecurePasswordProperty.Name); 
    passwordBinding.Source = myObject; 
    passwordBinding.ValidatesOnDataErrors = true; 
    // you can configure other binding stuff here 
    MyPassword.SetBinding(SecurePasswordProperty, passwordBinding); 
} 

private void MyPassword_Changed(object sender, RoutedEventArgs e) 
{ 
    // this should trigger binding and therefore validation 
    ((MyObject)DataContext).SecurePassword = MyPassword.SecurePassword; 
} 
1

私が覚えている限り、PasswordBoxに検証を追加する唯一の方法は、SecurePasswordのバインディングプロパティの設定ツールで新しいValidationExceptionをスローすることです。 PasswordBoxAssistantはこれを手伝ってくれません。にあり、途中で任意の「安全でない」文字列を使用せずに、あなたが

local:PasswordBoxAssistant.BoundPassword="{Binding Path=Password,Mode=TwoWay, 
UpdateSourceTrigger=Explicit}" 
+0

Hummmは例またはリンクを提供できますか?それは解決策として聞こえます。 – Sonhja

+0

これは私が働いていた古いアプリで見つけたものです:public SecureString NewPassword { get { return _newPassword; } セット { _newPassword = value; 文字列エラー= IsPasswordValid(); if(!string.IsNullOrEmpty(error)) { 新しいValidationException(エラー)をスローします。 } } } –

+0

Hummm、試してみてください。しかし、正確な解決策はRichard Deemingが投稿したものです(この場合)。しかし、私はこの特定のケースを私のコードでも持っているので、これも試してみるつもりです。 – Sonhja

2

別の解決策を結合に

<PasswordBox ... 
    local:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, 
     UpdateSourceTrigger=Explicit, 
     ValidatesOnDataErrors=True, 
     ValidatesOnExceptions=True}" 
/>