gpt4 book ai didi

c# - Passwordbox Validation.ErrorTemplate 未显示

转载 作者:太空宇宙 更新时间:2023-11-03 15:13:20 24 4
gpt4 key购买 nike

我正在尝试显示 PasswordBoxValidation.ErrorTemplate。但是,它没有显示。在同一表单上,我有一个用户名 TextBox 并且正确显示了 ErrorTemplate

数据模板中 PasswordBox 的 Xaml:

<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);
}
}
}
}
}

我在基本 View 模型中实现了 INotifyDataError 接口(interface)。

public class ViewModelBase : BindableBase, INotifyDataErrorInfo
{
private IDictionary<string, List<string>> errors
= new Dictionary<string, List<string>>();

public bool HasErrors
{
get
{
return this.errors.Count > 0;
}
}

public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

public IEnumerable GetErrors(string propertyName)
{
if ( this.errors.ContainsKey(propertyName) )
{
return this.errors[propertyName];
}
return null;
}

public void AddError(string propertyName, string error)
{
this.errors[propertyName] = new List<string> { error };
this.RaiseErrorsChanged(propertyName);
}

public void RemoveError(string propertyName)
{
if (this.errors.ContainsKey(propertyName))
{
this.errors.Remove(propertyName);
}
this.RaiseErrorsChanged(propertyName);
}

private void RaiseErrorsChanged(string propertyName)
{
if (this.ErrorsChanged != null)
{
this.ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
}
}
}

最佳答案

问题是,错误是在 DependencyObject 上引发的托管发生验证错误的数据绑定(bind)属性。在你的情况下 <behavior:PasswordBoxBehaviorBinding SPassword="{Binding Path=Password, ValidatesOnNotifyDataErrors=True}" />意味着,您可以在行为中读取您的错误。

在这一点上,我也想反对你对 SPassword 的绑定(bind)所做的奇怪的黑客攻击。 .只需正常设置值即可:

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从附加行为到主机控件以一种优雅的方式。所以基本上,您的选择是以某种方式将行为中的错误链接绑定(bind)到密码框,或者创建一个额外的绑定(bind)到您的属性,因为此绑定(bind)将使用相同的验证机制并因此设置 Validation.ErrorsPasswordBox 上.我决定绑定(bind) View 模型 PasswordPasswordBox.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>

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

还有一件事:我改变了 SPassword默认情况下双向绑定(bind)的属性:

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

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

关于c# - Passwordbox Validation.ErrorTemplate 未显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40135404/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com