Click here to Skip to main content
15,896,606 members
Articles / Desktop Programming / WPF

A (Mostly) Declarative Framework for Building Simple WPF-based Wizards

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
7 Mar 2011LGPL322 min read 19.3K   229   15  
A declarative framework for building WPF wizards.
/*
* Olbert.Utils.WPF
* Converters and Validators for use in WPF applications
* Copyright (C) 2011  Mark A. Olbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published 
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Reflection;

namespace Olbert.Utilities.WPF
{
    /// <summary>
    /// Returns true if the provided value, which should be a string, will fit within the specified
    /// database field. Objects other than strings, and null values, always return true.
    /// <para>This validator is intended to work with nHydrate entity objects, which expose the size
    /// of the database field in metadata. But it will work with any Type which follows the
    /// nHydrate approach to storing and accessing field lengths. If the supplied EntityType doesn't
    /// provide that support, true is always returned.</para>
    /// </summary>
    public class TextBoxLengthValidator : ValidationRule
    {
        /// <summary>
        /// Gets or sets the Type of the EntityObject that exposes the field against whose length
        /// we want to check the value being validated.
        /// </summary>
        public Type EntityType { get; set; }

        /// <summary>
        /// Gets or sets the name of the property against whose length we want to check the value
        /// being validated.
        /// </summary>
        public string PropertyName { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether blank values are allowed
        /// </summary>
        public bool BlankAllowed { get; set; }

        /// <summary>
        /// Validates a string value against a database field to see if the value will fit in the field.
        /// </summary>
        /// <param name="value">the value to check</param>
        /// <param name="cultureInfo">ignored</param>
        /// <returns>a ValidationResult object indicating whether the value will fit within the field</returns>
        public override ValidationResult Validate( object value, System.Globalization.CultureInfo cultureInfo )
        {
            // if we weren't given a value, or if it's not a string or string-derived object,
            // there's no point in checking further. Just return true.
            if( (value == null) 
                && (value.GetType() != typeof(string))
                && !value.GetType().IsSubclassOf(typeof(string)) ) return new ValidationResult(true, null);

            int length = ( (string) value ).Length;

            if( !BlankAllowed && (length == 0) )
                return new ValidationResult(false, "cannot be blank");

            Type fieldNames = EntityType.GetNestedType("FieldNameConstants");

            // if there was no nested FieldNameConstants Type the EntityType was probably not
            // an nHydrate entity, so we can't do the check. Just return true.
            if( fieldNames == null ) return new ValidationResult(true, null);

            object propField = Enum.Parse(fieldNames, PropertyName, true);

            MethodInfo getMaxLength = EntityType.GetMethod("GetMaxLength", BindingFlags.Static | BindingFlags.Public);

            // if there was no GetMaxLength method the EntityType was probably not
            // an nHydrate entity, so we can't do the check. Just return true.
            if( getMaxLength == null ) return new ValidationResult(true, null);

            int maxLength = (int) getMaxLength.Invoke(null, new object[] { propField });

            if( length > maxLength )
                return new ValidationResult(false, String.Format("length must be <= {0} characters", maxLength));

            return new ValidationResult(true, null);
        }
    }
}

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 GNU Lesser General Public License (LGPLv3)


Written By
Jump for Joy Software
United States United States
Some people like to do crossword puzzles to hone their problem-solving skills. Me, I like to write software for the same reason.

A few years back I passed my 50th anniversary of programming. I believe that means it's officially more than a hobby or pastime. In fact, it may qualify as an addiction Smile | :) .

I mostly work in C# and Windows. But I also play around with Linux (mostly Debian on Raspberry Pis) and Python.

Comments and Discussions