This project is read-only.
Instead of writing validation code into the CellValidating event of the DataGridView control is better to implement a validation system based on the IDataErrorInfo interface.

The UI with the ErrorProvider icon:
Validation.png

At the and the class to be validated looks like this:
public class Customer
	: Validable<Customer>
{
	public string Name { get; set; }

	public int Age { get; set; }
}

An example of a validation class:
public class CustomerValidator 
	: Validator<Customer>
{
	public override string Validate(Customer obj, string propertyName)
	{
		if (propertyName == Property(x => x.Name))
		{
			return string.IsNullOrWhiteSpace(obj.Name) ? "Must be not empty." : null;
		}

		if (propertyName == Property(x => x.Age))
		{
			if (obj.Age < 18)
			{
				return "Age must be greather than 18.";
			}
		}

		return ValidateOnStorage(obj);
	}

	private string ValidateOnStorage(Customer obj)
	{
		var customerRepository = 
			DependencyResolver
				.Resolve<CustomerRepository>();

		if (customerRepository.GetAll().Any(c => c.Name == obj.Name))
		{
			return string.Format("Customer with name {0} already exists.", obj.Name);
		}

		return null;
	}
}

And the base class:
public abstract class Validator<T> : 
	IValidator<T> where T : class
{
	public abstract string Validate(T obj, string propertyName);

	public string Validate(object obj, string propertyName)
	{
		return Validate((T)obj, propertyName);
	}

	/// <exception cref="ArgumentException">The given expression is not a MemberExpression.</exception>
	protected string Property<TProperty>(Expression<Func<T, TProperty>> expression)
	{
		var memberExpression = expression.Body as MemberExpression;

		if (memberExpression == null)
		{
			throw new ArgumentException("The given expression is not a MemberExpression.", "expression");
		}

		var propertyInfo =
			memberExpression.Member as PropertyInfo;

		if (propertyInfo == null)
		{
			throw new ArgumentException("The given expression is not a property.", "expression");
		}

		return propertyInfo.Name;
	}
}

Last edited Jul 27, 2011 at 8:08 PM by teoarch, version 6

Comments

No comments yet.