【发布时间】:2012-01-20 13:38:59
【问题描述】:
我一直很欣赏 Josh Smith 建立他的sample application 的方式。 而且我还尝试模拟他的应用程序的 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 不提供“密码”作为依赖属性。我不想违反 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"
我敢肯定,之所以会出现这个问题,是因为 Password 属性已被辅助类扩展。如果我放弃这种方法,我将不得不从 IDataErrorInfo 实现中删除 Password 属性,并且在登录按钮上单击必须验证它,向用户显示一个消息框。但并非不影响一致性。我不太了解依赖属性;有什么解决方法吗?以某种方式更改助手类会让我恢复红色错误消息吗?
【问题讨论】:
标签: wpf mvvm passwordbox custom-error-handling