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 不提供“密码”作为依赖属性。我不想打破 MVVM 尽可能避免代码落后的准则,所以很想去这里提到的PasswordBoxAssistant类. 否则这是一个很好的解决方案,保存一件事。它不允许我使用 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 属性,并且在登录按钮上单击必须验证它,向用户显示一个消息框。但并非不影响一致性。我不太了解依赖属性;有什么解决方法吗?以某种方式更改助手类会让我恢复红色错误消息吗?

4

2 回答 2

4

我没有ValidatesOnDataErrors=True在您的密码绑定中看到,所以也许这是您的问题。默认情况下,它设置为False这意味着绑定不会提醒 UI 任何验证错误。


也就是说,我认为这Password不是故意的,DependencyProperty因为您真的不应该将密码存储为纯文本。

通常我最终将PasswordBox.Password(或整个PasswordBox)作为 aCommandParameter传递给 my LoginCommand,然后它可以获取数据并对其执行任何操作。通常这意味着对它或其他东西进行散列并将其与存储的密码的散列进行比较以查看其是否相同。如果登录失败,我会将相关的错误消息写入我的 ViewModel 中的一个属性,该属性绑定到登录 UI。

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

不确定这是否是您的问题,但您没有关闭 PasswordBox. (即没有Validation.ErrorTemplate="{x:Null}

编辑:您可以使用Wpf Inspector之类的东西来检查的内容,Validation.ErrorsPasswordBox确保错误确实存在(或者甚至只是将 ItemsControl 绑定到它)?

于 2012-01-20T13:54:49.697 回答