65.9K
CodeProject 正在变化。 阅读更多。
Home

必需枚举验证属性

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (5投票s)

2015 年 12 月 5 日

CPOL

3分钟阅读

viewsIcon

19252

downloadIcon

120

此技巧介绍了一个可以应用于枚举属性的 ValidationAttribute。 通常的 RequiredValidationAttribute 通常可以工作,但如果数字被分配给枚举值,则默认值为零,这可能无效。

引言

这是我在另一位开发者遇到验证问题时为他创建的。 通常,人们不会将整数值分配给枚举,并且当分配整数值时,会有一个枚举被分配为零值。 RequiredAttibute 无法识别 0 可能不是有效的枚举,因此不会将其标记为错误。 通常,如果遇到此问题,枚举会用于 ComboBox 中,并且这只会是新记录的问题,因为尚未将值分配给 ComboBox,因此会使用默认值 “0”。

解决方案

using System;
using System.ComponentModel.DataAnnotations;

    public class RequiredEnumAttribute : RequiredAttribute
    {
        public override bool IsValid(object value)
        {
            if (value == null) return false;
            var type = value.GetType();
            return type.IsEnum && Enum.IsDefined(type, value);;
        }
}

这与 RequiredAttibute 非常相似,其中 IsValid 方法被覆盖。 最初,只需检查新值是否为 null,然后检查其值是否为枚举以及是否定义了该值。

示例

该示例有多个 ComboBox,它们的 ItemsSource 绑定到一个属性,该属性返回特定枚举定义的所有枚举的枚举。 SelectedItem 绑定到一个单独的属性,该属性是枚举的类型或枚举的 Nullable。 有两个属性用于绑定到 ItemsSource,一个用于没有数字分配的枚举,一个用于有数字分配的枚举。 具有数字分配的枚举没有分配给零的枚举。 从示例中可以看出,即使没有为枚举分配零值,枚举也会默认为整数值零。 如果没有赋值,则会自动进行零赋值。 将枚举属性设为 Nullable 意味着没有为枚举分配默认值,并且 RequiredAttribute 将强制用户选择一个值才能继续。 手动分配枚举值并且不为零分配枚举,并使用 RequiredEnumAttribute 可以达到相同的结果。

如果调查 XAML,您会看到绑定定义具有“ValidatesOnDataErrors=True”,这告诉绑定它需要使用 IDataErrorInfo 接口检查错误

<ComboBox Grid.Row="4"
          Grid.Column="1"
          Margin="5"
          VerticalAlignment="Center"
          ItemsSource="{Binding TypeBs}"
          SelectedItem="{Binding TypeB3,
                                 ValidatesOnDataErrors=True}" />

我经常忘记需要此属性,我知道我在与其他开发人员合作时发现过此错误。

使用此验证属性的装饰与任何其他验证属性没有什么不同

[RequiredEnum(ErrorMessage = "TypeB3 is required.")]
public TypeB TypeB3 { get; set; }

显然,我大大简化了属性,因为在实际应用程序中通常会引发 PropertyChanged 事件。 可以与 Required 装饰一起使用的所有参数都可以与 RequiredEnum 一起使用,因为它源自该类。

奖励

因为我必须在 ViewModel 中实现 IDataErrorInfo 以提供错误验证,所以我有一个名为 ValidationViewModelBase 的类。 ViewModel 使用它来实现 IDataErrorInfo 所需的 interface。 由于 C# 没有多重继承(我认为这是一个很大的错误,并且这是多重接口的一个很好的例子),如果您使用此类,您可能希望包含 INotifyPropertyChanged 接口。 但是,您可以轻松地调整此代码以供您使用,从而轻松提供使用验证属性时所需的 IDataErrorInfo 接口代码。

历史

  • 2015/12/05 初始版本
© . All rights reserved.