密码箱Validation.ErrorTemplate未显示

时间:2016-10-19 15:13:03

标签: c# wpf

我正在尝试显示Validation.ErrorTemplate的{​​{1}}。但是,它没有显示出来。在同一表单上,我有一个用户名PasswordBoxTextBox正确显示。

在datatempalte中的PasswordBox的Xaml:

ErrorTemplate

以下是我正在使用的附属物。

<PasswordBox Grid.Row="3" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType=ContentControl}}">                    
  <PasswordBox.Style>
    <Style>
      <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
          <ControlTemplate>
            <DockPanel LastChildFill="True">
              <TextBlock DockPanel.Dock="Right" Foreground="Red" FontSize="14" FontWeight="Bold">*</TextBlock>
              <Border BorderBrush="Red" BorderThickness="1">
                <AdornedElementPlaceholder/>
              </Border>
            </DockPanel>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </PasswordBox.Style>

  <i:Interaction.Behaviors>
    <behavior:PasswordBoxBehaviorBinding SPassword="{Binding Path=Password, ValidatesOnNotifyDataErrors=True}" />
  </i:Interaction.Behaviors>
</PasswordBox>

我在基本视图模型中实现了public class PasswordBoxBehaviorBinding : Behavior<PasswordBox> { public SecureString SPassword { get { return (SecureString)GetValue(PasswordProperty); } set { SetValue(PasswordProperty, value); } } public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register( "SPassword", typeof(SecureString), typeof(PasswordBoxBehaviorBinding), new PropertyMetadata(null)); protected override void OnAttached() { AssociatedObject.PasswordChanged += AssociatedObject_PasswordChanged; base.OnAttached(); } protected override void OnDetaching() { AssociatedObject.PasswordChanged += AssociatedObject_PasswordChanged; base.OnDetaching(); } private void AssociatedObject_PasswordChanged(object sender, RoutedEventArgs e) { var binding = BindingOperations.GetBindingExpression(this, PasswordProperty); if (binding != null) { if (binding.ResolvedSource != null) { PropertyInfo property = binding.ResolvedSource.GetType() .GetProperty(binding.ParentBinding.Path.Path); if (property != null) { property.SetValue(binding.ResolvedSource, AssociatedObject.SecurePassword); } } } } } 接口。

INotifyDataError

1 个答案:

答案 0 :(得分:0)

问题是,在承载发生验证错误的数据绑定属性的DependencyObject上引发了错误。在您的情况下,<behavior:PasswordBoxBehaviorBinding SPassword="{Binding Path=Password, ValidatesOnNotifyDataErrors=True}" />表示您可以在行为中阅读错误。

此时,我还想建议你对SPassword绑定所做的奇怪黑客攻击。只需正常设置值:

private void AssociatedObject_PasswordChanged(object sender, System.Windows.RoutedEventArgs e)
{
    SPassword = AssociatedObject.SecurePassword;
    // use debugger to verify, that the validation errors exist. Otherwise, no need for the following line of code
    var behaviorErrors = Validation.GetErrors(this);
}

不幸的是,我还没有找到,如何以优雅的方式将Validation.Errors从附加行为提升到主机控件。所以基本上,你的选择是以某种方式将错误从行为链接到密码箱或创建一个额外的绑定到你的属性,因为这个绑定将使用相同的验证机制,从而设置Validation.Errors PasswordBox。我决定将viewmodel Password绑定到PasswordBox.Tag以进行错误传播。

<PasswordBox Width="200" Height="100" Tag="{Binding Password,ValidatesOnNotifyDataErrors=True,Mode=OneWay}">
    <i:Interaction.Behaviors>
        <behavior:PasswordBoxBehaviorBinding SPassword="{Binding Password}"/>
    </i:Interaction.Behaviors>
</PasswordBox>

注意,我从绑定行为中删除了绑定错误验证,因为它无论如何都没用,我添加了Tag绑定的绑定错误验证。

还有一件事:默认情况下,我将SPassword属性更改为绑定twoway:

public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register(
    "SPassword",
    typeof(SecureString),
    typeof(PasswordBoxBehaviorBinding),
    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

否则,请确保正确设置绑定模式。