WPF Validation - Validation for Modal Dialog Boxes

Validation is one of those areas in WPF that still feels like a bit of a work in progress. The pretty much undocumented BindingGroup that has appeared in .NET 3.5 SP1 shows that some work is still going on on this (I suspect that BindingGroup has mainly appeared to support the upcoming DataGrid). But with a few tweaks validation in WPF is very useful and can do most of what is required.

The first tweak I use is for enforcing validation in modal dialogs. This static class has a method HandleOkButtonClick to be called when the dialog is being closed. This will validate each child in the logical tree, using the recursive CheckIsValid method. If validation passes then DialogResult is set to true, otherwise focus is put on the offending control.

public static class DialogBoxValidationHelper
{
    public static void HandleOkButtonClick(Window dialogWindow)
    {
        DependencyObject nodeFailingValidation;
        if (Validate.DialogBoxValidationHelper.CheckIsValid(dialogWindow, out nodeFailingValidation))
        {
            dialogWindow.DialogResult = true;
        }
        else
        {
            if (nodeFailingValidation is IInputElement)
            {
                Keyboard.Focus((IInputElement)nodeFailingValidation);
            }
        }
    }

    public static bool CheckIsValid(DependencyObject nodeToValidate, out DependencyObject nodeFailingValidation)
    {
        bool result = true;
        nodeFailingValidation = null;

        if (nodeToValidate == null)
            throw new ArgumentNullException(“nodeToValidate”);

        if( Validation.GetHasError(nodeToValidate) )
        {
            result = false;
            nodeFailingValidation = nodeToValidate;
        }
        else
        {
            foreach (object child in LogicalTreeHelper.GetChildren(nodeToValidate))
            {
                if (child is DependencyObject)
                {
                    result = CheckIsValid((DependencyObject)child, out nodeFailingValidation);
                    if (result == false) break;
                }
            }
        }

        return result;
    }
}

Tags:

Comments are closed.