Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / XAML
Tip/Trick

Required Enumeration Validation Attribute

Rate me:
Please Sign up or sign in to vote.
4.38/5 (5 votes)
5 Dec 2015CPOL3 min read 18.2K   91   4  
This tip presents a ValidationAttribute that can be applied to enumeration properties. The normal RequiredValidationAttribute normally works but if numbers are assigned to the enumeration values, the default value is zero and that may not be valid.

Introduction

This is something that I created for another developer when he was having issues with validation. Normally, one does not have integer values assigned to enumerations, and when they are assigned, there is an enumeration that is assigned the value zero. The RequiredAttibute does not recognize that 0 may not be a valid enumeration, so does not flag it as an error. Normally, if you encounter this problem, enumerations would be used in a ComboBox, and this would only be a problem for a new record where a value has not yet been assigned to the ComboBox, so the default of “0” is used.

Solution

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

This is a very similar to the RequiredAttibute where the IsValid method is overridden. Initially, just check that the new value is not null, and then check if its value is an enumeration, and that the value is defined.

The Sample

Image 1

The sample has a number of ComboBoxes that have their ItemsSource bound to a property that returns an enumeration of all the enumerations of a specific enumeration definition. The SelectedItem is bound to a separate property that is the type of the enumeration, or a Nullable of the enumeration. There are two properties for binding to the ItemsSource, one for an enumeration that does not have numeric assignments, and one that does. The one that has numeric assignments does not have an enumeration assigned to zero. As can be seen from the sample, the enumeration defaults to the integer value of zero even if a zero value is not assigned to the enumeration. A zero assignment will happen automatically if there are no assignment. Making an enumeration property Nullable will mean that there is no default value assigned to an enumeration, and the RequiredAttribute will force the user to select a value to continue. Manually assigning enumeration values and not assigning an enumeration for zero, and using the RequiredEnumAttribute can accomplish the same result.

If you investigate the XAML, you will see that the binding definition has a “ValidatesOnDataErrors=True” which is what tells the binding that it needs to check for errors using the IDataErrorInfo interface:

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

I have often forgotten about needing this attribute, and I know that I have found this error when working with other developers.

The decoration for using this validation attribute is no different from any other validation attribute:

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

I have obviously significantly simplified the property since normally would raise the PropertyChanged event in a real application. All the arguments that can be used with the Required decoration can be used with the RequiredEnum because it is derived from the class.

Bonus

Because I have to implement IDataErrorInfo in the ViewModel to provide error validation, I have a class called ValidationViewModelBase class. It is used by the ViewModel to implement the interface required for the IDataErrorInfo. Since C# does not have multiple inheritance (which I think is a big mistake, and this is a good example of where multiple interface), if you use this class, you will probably want to include the INotifyPropertyChanged interface. However, you can easily adapt this code for your use, and thus easily provide the IDataErrorInfo interface code required when validation attributes are used.

History

  • 12/05/2015 Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

Comments and Discussions

 
-- There are no messages in this forum --