In this post, I’ll show how to use Data Annotation Validation attributes to perform validation in a Windows Forms Application. Data Annotation Validation attributes enable you to perform model validation simply by decorating class properties with validation attributes such as the Required
, StringLength
, RegularExpression
, Range
, Url
, etc.
Introducing IDataErrorInfo
To show validation errors in Windows Forms, the frame work has an ErrorProvider
component. The framework also supports showing error in DataGridView
. To be able to show model errors in DataGridView
or showing errors using ErrorProvider
the model which you are using in data binding should implement IDataErrorInfo
. For example DataRowView
which is the main model which is usually used in classic ADO.NET applications, has implemented IDataErrorInfo
.
Here is the interface definition:
public interface IDataErrorInfo
{
string this[string columnName] { get; }
string Error { get; }
}
The interface contains two properties:
Error
: Gets an error message indicating what is wrong with this object.Item[String]
: Gets the error message for the property with the given name.
Implementing IDataErrorInfo using Data Annotations Validation Attributes
To bring validation attributes support to our model classes, we need to implement IDataErrorInfo
. There is a Validator
class in System.ComponentModel.DataAnnotations.dll
which has a couple of methods which allows us to validate an object or a property of an object using validation attributes:
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
public class BaseModel : IDataErrorInfo
{
[Browsable(false)]
public string this[string property]
{
get
{
var propertyDescriptor = TypeDescriptor.GetProperties(this)[property];
if (propertyDescriptor == null)
return string.Empty;
var results = new List<ValidationResult>();
var result = Validator.TryValidateProperty(
propertyDescriptor.GetValue(this),
new ValidationContext(this, null, null)
{ MemberName = property },
results);
if (!result)
return results.First().ErrorMessage;
return string.Empty;
}
}
[Browsable(false)]
public string Error
{
get
{
var results = new List<ValidationResult>();
var result = Validator.TryValidateObject(this,
new ValidationContext(this, null, null), results, true);
if (!result)
return string.Join("\n", results.Select(x => x.ErrorMessage));
else
return null;
}
}
}
Example
Let’s create a sample model and decorate its properties with validation attributes:
public class SampleModel : BaseModel
{
[Required]
[Range(1, 100)]
public int? Id { get; set; }
[Required]
[StringLength(10)]
[RegularExpression("w+")]
public string Name { get; set; }
[Required]
[StringLength(500, MinimumLength = 10)]
public string Description { get; set; }
[Required]
[Range(1, 100000)]
public int Price { get; set; }
[Required]
[Url]
public string Url { get; set; }
}
Then if you setup data binding using to SampleModel
using a BindingSource
and use an ErrorProvider
, then you can see error icon near the controls and if you hover on the error icon, you can see error message in tooltip:
Also if you use a DataGridView
, errors will be shown on cells and rows:
Download
You can clone or download the working example:
I am just starting with C#, so I am rather new to this. Could you please provide code for your form? How do I initiate validation? I should probably add an event listener to the Validating event, but then what method do I call?
Also I’m not sure how to use an ErrorProvider. I guess it would make this post even more complete with examples of that 🙂
Thanks!
Oops sorry, I should have checked the github of course.
Hi, How to Use RequiredIf by this scenario.
Thanks in Advance
Can this work with PropertyGrid? So far, all my attempts to get this to work with the PropertyGrid have been unsuccessful.
@XelaNimed I have an idea but haven’t tried that. You may want to take a look at this post and try to combine it with validation.
Do you happen to know how to disable the form “lock on” when entering data in a textbox? What I mean is that when the user is entering data in the textbox, he/she can not do anything else until the data inputted in the textbox is validated. For example, if a field requires to be a number, if the user enters a letter (or nothing at all) he/she won’t be able to change the field, select another option or even close the program. Thanks in advance.
How to show [DisplayName] instead of field name?