2012-01-20 26 views
2

私はいつもジョシュ・スミスがsample applicationを構築した方法を賞賛してきました。 また、自分のアプリケーションのViewModelがIDataErrorInfoプロパティを実装し、カスタムDataTemplateを介してユーザーの前にエラーをレンダリングする方法をエミュレートしようとしました。ここ は、彼がエラーを表示するために使用するデータテンプレートで次のようにWPFでのエラー処理PasswordBox

<DataTemplate DataType="{x:Type ValidationError}"> 
    <TextBlock FontSize="10" 
      FontStyle="Italic" 
      Foreground="Red" 
      HorizontalAlignment="Right" 
      Margin="0,1" 
      Text="{Binding Path=ErrorContent}"/> 
</DataTemplate> 

消費取得このデータテンプレートのワーキングサンプルがある:

<TextBox x:Name="txtUsername" 
     Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" 
     Width="300" 
     Margin="2" 
     Text="{Binding Path=Username, 
      ValidatesOnDataErrors=True, 
      UpdateSourceTrigger=PropertyChanged}" 
     Validation.ErrorTemplate="{x:Null}"/> 

<ContentPresenter Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" 
        Content="{Binding ElementName=txtUsername, 
         Path=(Validation.Errors).CurrentItem}"/> 

テキストボックスのデフォルトERRORTEMPLATE(赤その周囲に表示される境界線)は、新しいエラーテンプレートに置き換えられます。このエラーテンプレートでは、テキストボックスのすぐ下に配置されたコンテンツプレゼンターがエラー—を確かに優れた優雅なテンプレートに伝えます。

上記のコードを読んでいれば、ログインフォームを作成しようとしていると推測できます。

残念ながら、ログインフォームはパスワードを要求します(その後はPasswordBoxを使用)。 PasswordBoxは "Password"を依存関係プロパティとして提供しません。できるだけコードの背後にあるコードを避けようとするMVVMのガイドラインを破りたくないので、PasswordBoxAssistantクラスについてはhereと言いたいと思っていました。 これは別の点では素晴らしい解決策です。 Joshのデータテンプレートを使用してパスワードボックスを検証することはできません。 私のViewModelのパスワードプロパティが空でないことを検証しました。ユーザーがパスワードを入力しなくても、「ログイン」ボタンが有効になっていないため、プロパティの有効性が確認されています。しかし、このプロパティ検証の一環として設定した「パスワード入力」メッセージは、PasswordBoxの下にあるコンテンツプレゼンターによって表示されません。ここでコードが行く:

<Label Content="Password:" Grid.Column="0" Grid.Row="2" Margin="2" /> 

<PasswordBox x:Name="PasswordBox" 
      Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" 
      Margin="2" 
      Validation.ErrorTemplate="{x:Null}" 
      ff:PasswordBoxAssistant.BindPassword="true" 
      ff:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, 
       Mode=TwoWay, 
       UpdateSourceTrigger=PropertyChanged}"/> 

<ContentPresenter Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" 
        Content="{Binding ElementName=PasswordBox, 
        Path=(Validation.Errors).CurrentItem}"/> 
上記のコードではFFは名前空間の参照を意味していることは言うまでもない

xmlns:ff="clr-namespace:MyProject.UserViews" 

私は確信しているパスワードのプロパティが拡張されましたので、この問題が起きていますヘルパークラスによって。この方法を削除した場合、IDataErrorInfo実装からPasswordプロパティを削除し、Loginボタンをクリックするとその確認が必要になり、メッセージボックスが表示されます。しかし、一貫性を損なうことなく。私はDependency Propertiesについてあまり気にしていません。任意の回避策がありますか?何らかの方法でヘルパークラスを変更すると、赤色のエラーメッセージが表示されますか?

答えて

4

パスワードバインドにValidatesOnDataErrors=Trueが表示されない場合がありますが、これはおそらく問題です。デフォルトでは、これはFalseに設定されています。つまり、バインディングによってUIにアラートが表示されることはありません。

私はあなたが本当にプレーンテキストとしてパスワードを保存するべきではありませんので、 Passwordが意図的に DependencyPropertyはないと思う、と述べ

通常、私はそれがデータを取り、それを望んでいるものは何でも行うことができ、私のLoginCommandからCommandParameterとしてPasswordBox.Password(または全体PasswordBox)を渡してしまいます。通常、これはそれをハッシングするか、何かを保存されたパスワードのハッシュと比較して同じかどうかを確認することを意味します。ログインに失敗した場合は、関連するエラーメッセージを、ログインUIにバインドされているViewModelのプロパティに書き込みます。

<Button Command="{Binding LoginCommand}" 
     CommandParameter="{Binding ElementName=MyPasswordBox, Path=Password}" /> 
+0

お返事ありがとうございます。私はこの設計に飛び乗る前にこのオプションを持っていました。私の場合、ログインモジュールは従来のアプローチを保全するための正式な設計です。私の問題は、私がまだViewModelにパスワードを渡すための別の方法を装備できる設計ではありません。私の問題は、PasswordBoxAssistantがパスワードをブロックして、どのように検証されるのかです。 – James

+0

@Jamesパスワードバインドで 'ValidatesOnDataErrors =" True "を設定しましたか? – Rachel

+0

"あなたのパスワードバインディングにValidatesOnDataErrors = Trueが表示されないので、おそらくそれがあなたの問題です。" @レイチェルはキャッチがあった。それを指摘してくれてありがとう。私はあなたに宿題を投げ捨てることに恥ずかしいです。 – James

0

これが問題であるかどうかはわかりませんが、PasswordBoxのデフォルトのErrorTemplateをオフにしているわけではありません。 (すなわち無Validation.ErrorTemplate="{x:Null}

EDIT:あなたはエラーが実際に存在している(あるいは単にそれにItemsControlにバインド)することを確実にするためにPasswordBoxValidation.Errorsの内容をチェックするためにWpf Inspectorのようなものを使用することはできますか?

+0

それをマークしてくれてありがとうございますが、それは問題ではありません。デフォルトのエラーテンプレートをオフにしないと、デフォルトのエラーテンプレートが表示されます。しかし、何も現れていない。 – James

関連する問題