gpt4 book ai didi

c# - 如何在验证另一个属性时触发对一个属性的验证,使用自定义 ValidationAttribute 和 INotifyDataErrorInfo

转载 作者:太空狗 更新时间:2023-10-29 23:38:45 25 4
gpt4 key购买 nike

直到最近,我一直在使用 IDataErrorInfo 的自定义扩展版本界面。我的扩展使我能够同时处理多个错误,到目前为止,它对我来说非常有用。但是,随着 INotifyDataErrorInfo 的引入界面,我想我会尝试一下,看看是否有任何改进。

在学习了一些在线教程之后,我开始使用各种 ValidationAttribute来自 System.ComponentModel.DataAnnotations namespace .使用这些 Attribute让您提供如下基本验证规则:

[MinLength(3, ErrorMessage = "Name must be longer than 3 characters.")]
public string Name
{
get { return name; }
set { name = value; NotifyPropertyChanged("Name"); Validate("Name", name); }
}

最初,它看起来还不错,因为错误消息直接插入 Valaidation.Errors应用中可用的集合 ErrorTemplate秒。然而,大多数内置的验证规则都是非常基本的,我习惯于实现涉及其他属性值的复杂验证规则。

所以我着手寻找一种方法来创建一个涉及多个属性的简单验证规则:必须设置两个或多个字段之一的规则。所以我声明了一个扩展 ValidationAttribute 的类在网上搜索后,找到了一种访问其他属性值的方法。

我用自定义 ErrorTemplate 构建了一个基本 UI适用于每个 TextBox , 显示 Validation.Errors数据绑定(bind)属性的集合:

<ControlTemplate x:Key="ErrorTemplate">
<StackPanel Orientation="Horizontal">
<Border BorderBrush="#4FFF0000" BorderThickness="1" Margin="0,10">
<AdornedElementPlaceholder />
</Border>
<Image Name="WarningImage" Source="pack://application:,,,/WpfApplication1;component/Images/Warning_16.png" Margin="5,0,0,0" Tag="{Binding}" />
<Popup PlacementTarget="{Binding ElementName=WarningImage}" Placement="Right" Margin="5,0,0,0" AllowsTransparency="True" IsOpen="True">
<Border BorderThickness="1" BorderBrush="#4FFF0000" CornerRadius="5" Background="White" Padding="5" Margin="10">
<Border.Effect>
<DropShadowEffect Color="Red" Opacity="0.5" BlurRadius="15" ShadowDepth="0" />
</Border.Effect>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ErrorContent}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</Popup>
</StackPanel>
</ControlTemplate>

我的习惯Attribute设置在 Name 上属性,我设法添加了一个 ValidationResult进入Validation.Errors当两个属性都没有设置时通过界面收集,但问题是:如果我将一个值添加到另一个 TextBox 中es数据绑定(bind)其他需要的属性,错误信息在第一个TextBox会留在那里。

如果我回到第一个TextBox并输入一些东西,然后验证就会起作用,所以即使我删除了该值,它仍然知道设置了一个必需的属性。因此验证代码有效,但问题是对其他必需属性的属性更改不会触发 Name 中的验证。属性(property)。

即使我应用了相同的自定义 Attribute对于其他必需的属性,同样的事情发生了......每个验证错误只有在输入其相关的 TextBox 时才会清除。 .我还尝试了内置的 CustomValidationAttribute这使我们能够调用类中的方法进行验证,但最终结果是一样的。

验证代码有效,但不会由其他必需的属性更改触发。我什至试着调用Validate方法,传入其他属性的名称,但以连续循环结束。所以问题是,当另一个属性已验证时,如何触发对一个属性的验证?

最佳答案

这是我在包含 FromTo 属性的类中所做的。我想验证 From 小于或等于 To

使用 CustomValidationAttribute 应用验证逻辑,这比创建您自己的验证属性类更容易。您只需告诉它您的类的类型,以及要调用的包含您的验证逻辑的方法的名称(尽管该方法必须具有特定的签名)。这是我的相关代码:-

    [CustomValidation(typeof(MyModel), "ValidateRange")]
public double From
{
get
{
return _from;
}
set
{
if (_from != value)
{
_from = value;
OnPropertyChanged("From");

// Validate the other side
ValidateProperty("To", _to);
}
}
}

[CustomValidation(typeof(MyModel), "ValidateRange")]
public double To
{
get
{
return _to;
}
set
{
if (_to != value)
{
_to = value;
OnPropertyChanged("To");

// Validate the other side
ValidateProperty("From", _from);
}
}
}

private static ValidationResult ValidateRange(ValidationContext validationContext)
{
var model = validationContext.ObjectInstance as MyModel;

if (model.From > model.To)
{
return new ValidationResult("Invalid range");
}

return null;
}

如您所见,一个属性 setter 中的代码强制验证“其他”属性,正如您在上一段中提到的那样。它没有理由进入无限循环,除非您的验证代码试图设置其中一个属性,这将触发对 Validate() 的另一次调用,依此类推。

关于c# - 如何在验证另一个属性时触发对一个属性的验证,使用自定义 ValidationAttribute 和 INotifyDataErrorInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24874418/

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