Click here to Skip to main content
15,891,372 members
Articles / Desktop Programming / WPF

Validizor - A Validation Control for WPF

Rate me:
Please Sign up or sign in to vote.
4.66/5 (16 votes)
17 Oct 2007CPOL7 min read 94.6K   4.3K   58  
A WPF validation control for validating your data objects.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Globalization;
using System.ComponentModel;
using System.Reflection;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Integration;

namespace Validize
{
    /// <remarks>
    /// (c) 2007 Martin Bennedik, see BSD license in the license.txt file
    /// http://www.bennedik.de
    /// 
    /// Modified by Buzz Weetman October, 2007 for Validize control.
    ///     - Changed to Validize namespace
    ///     - Modified FormatErrorMessage method to create bulleted list.
    ///     - Hardcoded error messages
    /// </remarks>
    
    /// <summary>
    /// The EnterpriseValidationRule integrates WPF with the Validation Application Block (VAB) of Enterprise Library 3.0.
    /// It is similar to the VAB ASP.NET integration's PropertyProxyValidator but implements a 
    /// WPF ValidationRule instead of an ASP.NET BaseValidator.
    /// An ErrorProvider can be used to conveniently initialize EnterpriseValidationRules.
    /// </summary>
    public class EnterpriseValidationRule : ValidationRule, IValidationIntegrationProxy
    {
        protected object value;

        public override System.Windows.Controls.ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            this.value = value;

            Validator validator = new ValidationIntegrationHelper(this).GetValidator();

            if (validator != null)
            {
                ValidationResults validationResults = validator.Validate(this);

                string errorMessage = FormatErrorMessage(validationResults);
                return new System.Windows.Controls.ValidationResult(validationResults.IsValid, errorMessage);
            }
            else
            {
                return new System.Windows.Controls.ValidationResult(true, null);
            }
        }

        internal static string FormatErrorMessage(ValidationResults results)
        {
            StringBuilder stringBuilder = new StringBuilder();

            if (!results.IsValid)
            {
                bool needsNewLine = false;
                foreach (Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult validationResult in results)
                {
                    if (needsNewLine)
                        stringBuilder.Append(Environment.NewLine);
                    else
                        needsNewLine = true;
                    stringBuilder.Append('\u2022'); // bullet
                    stringBuilder.Append(' ');
                    stringBuilder.Append(validationResult.Message);
                }
            }

            return stringBuilder.ToString();
        }

        internal bool GetValue(out object value, out string valueAccessFailureMessage)
        {
            ValidationIntegrationHelper helper = new ValidationIntegrationHelper(this);

            return helper.GetValue(out value, out valueAccessFailureMessage);
        }

        private string sourceTypeName;
        /// <summary>
        /// Gets or sets the name of the type to use a source for validation specifications.
        /// </summary>
        public string SourceTypeName
        {
            get { return sourceTypeName; }
            set { sourceTypeName = value; }
        }

        private string propertyName;
        /// <summary>
        /// Gets or sets the name of the property to use as soource for validation specifications.
        /// </summary>
        public string PropertyName
        {
            get { return propertyName; }
            set { propertyName = value; }
        }

        private string rulesetName;
        /// <summary>
        /// Gets or sets the name of the ruleset to use when retrieving validation specifications.
        /// </summary>
        [DefaultValue("")]
        public string RulesetName
        {
            get { return rulesetName != null ? rulesetName : string.Empty; }
            set { rulesetName = value; }
        }

        private ValidationSpecificationSource specificationSource = ValidationSpecificationSource.Both;
        /// <summary>
        /// Gets or sets the <see cref="ValidationSpecificationSource"/> indicating where to get validation specifications from.
        /// </summary>
        [DefaultValue(ValidationSpecificationSource.Both)]
        public ValidationSpecificationSource SpecificationSource
        {
            get { return specificationSource; }
            set { specificationSource = value; }
        }

        /// <summary>
        /// Occurs when value conversion is required by the control to perform validation.
        /// </summary>
        /// <remarks>
        /// The ValueConvert event is raised when value conversion is required by the control to perform validation. 
        /// This event is used to provide a custom value conversion routine for an input control, 
        /// such as a <see cref="System.Web.UI.WebControls.TextBox"/> control.
        /// </remarks>
        /// <seealso cref="ValueConvertEventArgs"/>
        public event EventHandler<ValueConvertEventArgs> ValueConvert;

        #region IValidationIntegrationProxy Members

        object IValidationIntegrationProxy.GetRawValue()
        {
            return value;
        }

        MemberValueAccessBuilder IValidationIntegrationProxy.GetMemberValueAccessBuilder()
        {
            return new PropertyMappedValidatorValueAccessBuilder();
        }

        void IValidationIntegrationProxy.PerformCustomValueConversion(ValueConvertEventArgs e)
        {
            if (this.ValueConvert != null)
            {
                this.ValueConvert(this, e);
            }
        }

        bool IValidationIntegrationProxy.ProvidesCustomValueConversion
        {
            get { return this.ValueConvert != null; }
        }

        string IValidationIntegrationProxy.Ruleset
        {
            get { return this.RulesetName; }
        }

        ValidationSpecificationSource IValidationIntegrationProxy.SpecificationSource
        {
            get { return this.SpecificationSource; }
        }

        string IValidationIntegrationProxy.ValidatedPropertyName
        {
            get { return this.PropertyName; }
        }

        Type IValidationIntegrationProxy.ValidatedType
        {
            get
            {
                if (string.IsNullOrEmpty(this.sourceTypeName))
                {
                    throw new InvalidOperationException("The source type name cannot be null.");
                }
                Type validatedType = Type.GetType(this.SourceTypeName, false, false);
                if (validatedType == null)
                {
                    throw new InvalidOperationException(
                        string.Format(CultureInfo.CurrentUICulture,
                            "The source type could not be found for name \"{0}\".",
                            this.sourceTypeName));
                }

                return validatedType;
            }
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer
United States United States
software engineer

Comments and Discussions