2

Josh Smith のサンプル アプリケーションの作成方法には、いつも感心しています。また、彼のアプリケーションの ViewModels が IDataErrorInfo プロパティを実装し、カスタム DataTemplate を介してユーザーの前にエラーをレンダリングする方法をエミュレートしようとしました。エラーを表示するために彼が使用するデータ テンプレートは次のとおりです。

<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クラスに行きたくなりました. そうでなければ、これは良い解決策です.1つだけ保存してください。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"

Password プロパティがヘルパー クラスによって拡張されているため、この問題が発生していると確信しています。このアプローチをやめると、Password プロパティを IDataErrorInfo 実装から削除する必要があり、[ログイン] ボタンのクリック時にそれを確認して、ユーザーにメッセージ ボックスを表示する必要があります。しかし、一貫性を損なうことなくではありません。依存関係プロパティについてはあまり知りません。回避策はありますか?何らかの方法でヘルパー クラスを変更すると、赤いエラー メッセージが表示されるようになりますか?

4

2 に答える 2

4

パスワードのバインドが表示されないValidatesOnDataErrors=Trueため、おそらくそれが問題です。これFalseは、バインディングが検証エラーを UI に警告しないことを意味します。


そうは言っても、パスワードをプレーンテキストとして保存するべきではないためPassword、意図的に a ではないと思います。DependencyProperty

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

<Button Command="{Binding LoginCommand}" 
        CommandParameter="{Binding ElementName=MyPasswordBox, Path=Password}" />
于 2012-01-20T14:25:51.043 に答える
0

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

編集: Wpf InspectorValidation.Errorsのようなものを使用して、の内容をチェックしPasswordBoxて、エラーが実際に存在することを確認できますか?

于 2012-01-20T13:54:49.697 に答える