validation.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Controls / validation.cs / 1 / validation.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) 2005 by Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: 
//     Validation-related methods and DependencyProperties
// 
// See specs at http://avalon/connecteddata/Specs/Validation.mht
//
// History:
//  02/03/2005       mharper: created. 
//
//--------------------------------------------------------------------------- 
 
using System;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics; 
using System.Windows;
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Media;
 
using MS.Internal.Controls;
using MS.Internal.Data;
using MS.Internal.KnownBoxes;
using MS.Utility; 

namespace System.Windows.Controls 
{ 

    ///  
    ///     Validation-related methods and DependencyProperties
    /// 
    public static class Validation
    { 

        ///  
        ///     ValidationError event 
        /// 
        public static readonly RoutedEvent ErrorEvent = 
                EventManager.RegisterRoutedEvent("ValidationError",
                                                    RoutingStrategy.Bubble,
                                                    typeof(EventHandler),
                                                    typeof(Validation)); 

 
        ///  
        ///     Adds a handler for the ValidationError attached event
        ///  
        /// UIElement or ContentElement that listens to this event
        /// Event Handler to be added
        public static void AddErrorHandler(DependencyObject element, EventHandler handler)
        { 
            FrameworkElement.AddHandler(element, ErrorEvent, handler);
        } 
 
        /// 
        ///     Removes a handler for the ValidationError attached event 
        /// 
        /// UIElement or ContentElement that listens to this event
        /// Event Handler to be removed
        public static void RemoveErrorHandler(DependencyObject element, EventHandler handler) 
        {
            FrameworkElement.RemoveHandler(element, ErrorEvent, handler); 
        } 

        ///  
        ///     The key needed to set the publicly read-only ValidationErrors property.
        /// 
        internal static readonly DependencyPropertyKey ErrorsPropertyKey =
                DependencyProperty.RegisterAttachedReadOnly("Errors", 
                                    typeof(ReadOnlyObservableCollection), typeof(Validation),
                                    new FrameworkPropertyMetadata( 
                                            ValidationErrorCollection.Empty, 
                                            FrameworkPropertyMetadataOptions.NotDataBindable));
 
        /// 
        ///     ValidationErrors DependencyProperty.
        ///     holds the list of all active validation errors of any data binding targeting the hosting element.
        ///  
        /// 
        ///     The application cannot modify the content of this collection. 
        ///  
        public static readonly DependencyProperty ErrorsProperty =
                ErrorsPropertyKey.DependencyProperty; 

        ///  Static accessor for Validation.Errors property 
        /// 
        ///     The application cannot modify the content of this collection. 
        /// 
        ///  DependencyObject element cannot be null  
        public static ReadOnlyObservableCollection GetErrors(DependencyObject element) 
        {
            if (element == null) 
                throw new ArgumentNullException("element");

            return (ReadOnlyObservableCollection) element.GetValue(ErrorsProperty);
        } 

        ///  
        ///     holds the internally modifiable collection of validation errors. 
        /// 
        internal static readonly DependencyProperty ValidationErrorsInternalProperty = 
                DependencyProperty.RegisterAttached("ErrorsInternal",
                        typeof(ValidationErrorCollection), typeof(Validation),
                        new FrameworkPropertyMetadata(
                                (ValidationErrorCollection)null, 
                                new PropertyChangedCallback(OnErrorsInternalChanged)));
 
        // Update HasErrors and Invalidate the public ValidationErrors property whose GetOverride will return 
        // the updated value of ValidationErrorsInternal, nicely wrapped into a ReadOnlyCollection
        private static void OnErrorsInternalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            ValidationErrorCollection newErrors = e.NewValue as ValidationErrorCollection;

            if (newErrors != null) 
            {
                d.SetValue(ErrorsPropertyKey, new ReadOnlyObservableCollection(newErrors)); 
            } 
            else
            { 
                d.ClearValue(ErrorsPropertyKey);
            }
        }
 
        internal static ValidationErrorCollection GetErrorsInternal(DependencyObject target)
        { 
            return (ValidationErrorCollection) target.GetValue(Validation.ValidationErrorsInternalProperty); 
        }
 
        /// 
        ///     The key needed set a read-only property.
        /// 
        internal static readonly DependencyPropertyKey HasErrorPropertyKey = 
                DependencyProperty.RegisterAttachedReadOnly("HasError",
                        typeof(bool), typeof(Validation), 
                        new FrameworkPropertyMetadata( 
                                BooleanBoxes.FalseBox,
                                FrameworkPropertyMetadataOptions.NotDataBindable)); 

        /// 
        ///     HasError DependencyProperty is true if any binding on the target element
        ///     has a validation error. 
        /// 
        public static readonly DependencyProperty HasErrorProperty= 
            HasErrorPropertyKey.DependencyProperty; 

        ///  Static accessor for HasError property  
        ///  DependencyObject element cannot be null 
        public static bool GetHasError(DependencyObject element)
        {
            if (element == null) 
                throw new ArgumentNullException("element");
 
            return (bool) element.GetValue(HasErrorProperty); 
        }
 
        /// 
        ///     Template used to generate validation error feedback on the AdornerLayer.  Default
        ///     Template is:
        ///  
        ///     
        ///         
        ///      
        /// 
        ///  
        public static readonly DependencyProperty ErrorTemplateProperty =
                DependencyProperty.RegisterAttached("ErrorTemplate",
                            typeof(ControlTemplate), typeof(Validation),
                            new FrameworkPropertyMetadata( 
                                CreateDefaultErrorTemplate(),
                                FrameworkPropertyMetadataOptions.NotDataBindable, 
                                new PropertyChangedCallback(OnErrorTemplateChanged))); 

 
        ///  Static accessor for ErrorTemplate property 
        ///  DependencyObject element cannot be null 
        [AttachedPropertyBrowsableForType(typeof(DependencyObject))]
        public static ControlTemplate GetErrorTemplate(DependencyObject element) 
        {
            if (element == null) 
                throw new ArgumentNullException("element"); 

            return element.GetValue(ErrorTemplateProperty) as ControlTemplate; 
        }

        ///  Static modifier for ErrorTemplate property 
        ///  DependencyObject element cannot be null  
        public static void SetErrorTemplate(DependencyObject element, ControlTemplate value)
        { 
            if (element == null) 
                throw new ArgumentNullException("element");
 
            // (perf) don't set if the existing value is already correct
            object oldValue = element.ReadLocalValue(ErrorTemplateProperty);
            if (!Object.Equals(oldValue, value))
                element.SetValue(ErrorTemplateProperty, value); 
        }
 
        // when ErrorTemplate changes, redraw the currently visible adorner 
        private static void OnErrorTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            if (GetHasError(d))
            {
                ShowValidationAdorner(d, false);
                ShowValidationAdorner(d, true); 
            }
        } 
 

        ///  
        ///     Designates the alternative element to which validation feedback
        ///     should be directed.
        /// 
        public static readonly DependencyProperty ValidationAdornerSiteProperty = 
                DependencyProperty.RegisterAttached("ValidationAdornerSite",
                            typeof(DependencyObject), typeof(Validation), 
                            new FrameworkPropertyMetadata((DependencyObject)null, 
                                                        new PropertyChangedCallback(OnValidationAdornerSiteChanged)));
 

        ///  Static accessor for ValidationAdornerSite property 
        ///  DependencyObject element cannot be null 
        [AttachedPropertyBrowsableForType(typeof(DependencyObject))] 
        public static DependencyObject GetValidationAdornerSite(DependencyObject element)
        { 
            if (element == null) 
                throw new ArgumentNullException("element");
 
            return element.GetValue(ValidationAdornerSiteProperty) as DependencyObject;
        }

        ///  Static modifier for ValidationAdornerSite property  
        ///  DependencyObject element cannot be null 
        public static void SetValidationAdornerSite(DependencyObject element, DependencyObject value) 
        { 
            if (element == null)
                throw new ArgumentNullException("element"); 

            element.SetValue(ValidationAdornerSiteProperty, value);
        }
 
        // when Site property changes, update the SiteFor property on the other end
        private static void OnValidationAdornerSiteChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        { 
            DependencyObject oldSite = (DependencyObject)e.OldValue;
            DependencyObject newSite = (DependencyObject)e.NewValue; 

            if (oldSite != null)
            {
                oldSite.ClearValue(ValidationAdornerSiteForProperty); 
            }
 
            if (newSite != null) 
            {
                if (d != GetValidationAdornerSiteFor(newSite)) 
                {
                    SetValidationAdornerSiteFor(newSite, d);
                }
            } 

            // if the adorner is currently visible, move it to the new site 
            if (GetHasError(d)) 
            {
                if (oldSite == null) 
                {
                    oldSite = d;
                }
                ShowValidationAdornerHelper(d, oldSite, false); 
                ShowValidationAdorner(d, true);
            } 
        } 

 
        /// 
        ///     Designates the element for which the current element should server
        ///     as the .
        ///  
        public static readonly DependencyProperty ValidationAdornerSiteForProperty =
                DependencyProperty.RegisterAttached("ValidationAdornerSiteFor", 
                            typeof(DependencyObject), typeof(Validation), 
                            new FrameworkPropertyMetadata((DependencyObject)null,
                                                        new PropertyChangedCallback(OnValidationAdornerSiteForChanged))); 


        ///  Static accessor for ValidationAdornerSiteFor property 
        ///  DependencyObject element cannot be null  
        [AttachedPropertyBrowsableForType(typeof(DependencyObject))]
        public static DependencyObject GetValidationAdornerSiteFor(DependencyObject element) 
        { 
            if (element == null)
                throw new ArgumentNullException("element"); 

            return element.GetValue(ValidationAdornerSiteForProperty) as DependencyObject;
        }
 
        ///  Static modifier for ValidationAdornerSiteFor property 
        ///  DependencyObject element cannot be null  
        public static void SetValidationAdornerSiteFor(DependencyObject element, DependencyObject value) 
        {
            if (element == null) 
                throw new ArgumentNullException("element");

            element.SetValue(ValidationAdornerSiteForProperty, value);
        } 

        // when SiteFor property changes, update the Site property on the other end 
        private static void OnValidationAdornerSiteForChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            DependencyObject oldSiteFor = (DependencyObject)e.OldValue; 
            DependencyObject newSiteFor = (DependencyObject)e.NewValue;

            if (oldSiteFor != null)
            { 
                oldSiteFor.ClearValue(ValidationAdornerSiteProperty);
            } 
 
            if (newSiteFor != null)
            { 
                if (d != GetValidationAdornerSite(newSiteFor))
                {
                    SetValidationAdornerSite(newSiteFor, d);
                } 
            }
        } 
 

        internal static void ShowValidationAdorner(DependencyObject targetElement, bool show) 
        {
            // redirect the adorner to the designated site, if any
            DependencyObject adornerSite = GetValidationAdornerSite(targetElement);
            if (adornerSite == null) 
            {
                adornerSite = targetElement; 
            } 

            ShowValidationAdornerHelper(targetElement, adornerSite, show); 
        }

        private static void ShowValidationAdornerHelper(DependencyObject targetElement, DependencyObject adornerSite, bool show)
        { 
            UIElement siteUIElement = adornerSite as UIElement;
 
            if (siteUIElement != null) 
            {
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(siteUIElement); 

                if (adornerLayer == null)
                    return;
 
                TemplatedAdorner validationAdorner = siteUIElement.ReadLocalValue(ValidationAdornerProperty) as TemplatedAdorner;
 
                if (show && validationAdorner == null) 
                {
                    // get the template from the site, or from the target element 
                    ControlTemplate validationTemplate = GetErrorTemplate(siteUIElement);
                    if (validationTemplate == null)
                    {
                        validationTemplate = GetErrorTemplate(targetElement); 
                    }
 
                    if (validationTemplate != null) 
                    {
                        validationAdorner = new TemplatedAdorner(siteUIElement, validationTemplate); 
                        adornerLayer.Add(validationAdorner);

                        siteUIElement.SetValue(ValidationAdornerProperty, validationAdorner);
                    } 
                }
                else if (!show && validationAdorner != null) 
                { 
                    validationAdorner.ClearChild();
                    adornerLayer.Remove(validationAdorner); 
                    siteUIElement.ClearValue(ValidationAdornerProperty);
                }
            }
        } 

 
        ///  
        /// Mark this BindingExpression as invalid.  If the BindingExpression has been
        /// explicitly marked invalid in this way, then it will remain 
        /// invalid until ClearInvalid is called or another transfer to the source validates successfully.
        /// 
        public static void MarkInvalid(BindingExpressionBase bindingExpression, ValidationError validationError)
        { 
            if (bindingExpression == null)
                throw new ArgumentNullException("bindingExpression"); 
            if (validationError == null) 
                throw new ArgumentNullException("validationError");
 
            bindingExpression.UpdateValidationError(validationError);
        }

        ///  
        /// Clears the ValidationError that was set through a call
        /// to MarkInvalid or a previously failed validation of that BindingExpression. 
        ///  
        public static void ClearInvalid(BindingExpressionBase bindingExpression)
        { 
            if (bindingExpression == null)
                throw new ArgumentNullException("bindingExpression");
            bindingExpression.UpdateValidationError(null);
        } 

        // add a validation error to the given element 
        internal static void AddValidationError(ValidationError validationError, DependencyObject targetElement, bool shouldRaiseEvent) 
        {
            if (targetElement == null) 
                return;

            bool wasValid;
            ValidationErrorCollection validationErrors = GetErrorsInternal(targetElement); 

            if (validationErrors == null) 
            { 
                wasValid = true;
                validationErrors = new ValidationErrorCollection(); 
                validationErrors.Add(validationError);
                targetElement.SetValue(Validation.ValidationErrorsInternalProperty, validationErrors);
            }
            else 
            {
                wasValid = (validationErrors.Count == 0); 
                validationErrors.Add(validationError); 
            }
 
            if (wasValid)
            {
                targetElement.SetValue(HasErrorPropertyKey, BooleanBoxes.TrueBox);
            } 

            if (shouldRaiseEvent) 
            { 
                OnValidationError(targetElement, validationError, ValidationErrorEventAction.Added);
            } 

            if (wasValid)
            {
                ShowValidationAdorner(targetElement, true); 
            }
        } 
 
        // remove a validation error from the given element
        internal static void RemoveValidationError(ValidationError validationError, DependencyObject targetElement, bool shouldRaiseEvent) 
        {
            if (targetElement == null)
                return;
 
            ValidationErrorCollection validationErrors = GetErrorsInternal(targetElement);
            if (validationErrors == null || validationErrors.Count == 0 || !validationErrors.Contains(validationError)) 
                return; 

            bool isValid = (validationErrors.Count == 1);   // about to remove the last error 

            if (isValid)
            {
                targetElement.ClearValue(HasErrorPropertyKey); 
            }
 
            validationErrors.Remove(validationError); 

            if (shouldRaiseEvent) 
            {
                OnValidationError(targetElement, validationError, ValidationErrorEventAction.Removed);
            }
 
            if (isValid)
            { 
                targetElement.ClearValue(ValidationErrorsInternalProperty); 
                ShowValidationAdorner(targetElement, false);
            } 
        }

        static void OnValidationError(DependencyObject source, ValidationError validationError, ValidationErrorEventAction action)
        { 
            ValidationErrorEventArgs args = new ValidationErrorEventArgs(validationError, action);
 
            if (source is ContentElement) 
                ((ContentElement)source).RaiseEvent(args);
            else if (source is UIElement) 
                ((UIElement)source).RaiseEvent(args);
            else if (source is UIElement3D)
                ((UIElement3D)source).RaiseEvent(args);
        } 

        private static ControlTemplate CreateDefaultErrorTemplate() 
        { 
            ControlTemplate defaultTemplate = new ControlTemplate(typeof(Control));
 
            //
            //        
            //
 
            FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border), "Border");
            border.SetValue(Border.BorderBrushProperty, Brushes.Red); 
            border.SetValue(Border.BorderThicknessProperty, new Thickness(1)); 

            FrameworkElementFactory adornedElementPlaceHolder = new FrameworkElementFactory(typeof(AdornedElementPlaceholder), "Placeholder"); 

            border.AppendChild(adornedElementPlaceHolder);

            defaultTemplate.VisualTree = border; 
            defaultTemplate.Seal();
 
            return defaultTemplate; 
        }
 
        /// 
        ///     Reference to the ValidationAdorner
        /// 
        private static readonly DependencyProperty ValidationAdornerProperty = 
                DependencyProperty.RegisterAttached("ValidationAdorner",
                        typeof(TemplatedAdorner), typeof(Validation), 
                        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.NotDataBindable)); 

    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) 2005 by Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: 
//     Validation-related methods and DependencyProperties
// 
// See specs at http://avalon/connecteddata/Specs/Validation.mht
//
// History:
//  02/03/2005       mharper: created. 
//
//--------------------------------------------------------------------------- 
 
using System;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics; 
using System.Windows;
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Media;
 
using MS.Internal.Controls;
using MS.Internal.Data;
using MS.Internal.KnownBoxes;
using MS.Utility; 

namespace System.Windows.Controls 
{ 

    ///  
    ///     Validation-related methods and DependencyProperties
    /// 
    public static class Validation
    { 

        ///  
        ///     ValidationError event 
        /// 
        public static readonly RoutedEvent ErrorEvent = 
                EventManager.RegisterRoutedEvent("ValidationError",
                                                    RoutingStrategy.Bubble,
                                                    typeof(EventHandler),
                                                    typeof(Validation)); 

 
        ///  
        ///     Adds a handler for the ValidationError attached event
        ///  
        /// UIElement or ContentElement that listens to this event
        /// Event Handler to be added
        public static void AddErrorHandler(DependencyObject element, EventHandler handler)
        { 
            FrameworkElement.AddHandler(element, ErrorEvent, handler);
        } 
 
        /// 
        ///     Removes a handler for the ValidationError attached event 
        /// 
        /// UIElement or ContentElement that listens to this event
        /// Event Handler to be removed
        public static void RemoveErrorHandler(DependencyObject element, EventHandler handler) 
        {
            FrameworkElement.RemoveHandler(element, ErrorEvent, handler); 
        } 

        ///  
        ///     The key needed to set the publicly read-only ValidationErrors property.
        /// 
        internal static readonly DependencyPropertyKey ErrorsPropertyKey =
                DependencyProperty.RegisterAttachedReadOnly("Errors", 
                                    typeof(ReadOnlyObservableCollection), typeof(Validation),
                                    new FrameworkPropertyMetadata( 
                                            ValidationErrorCollection.Empty, 
                                            FrameworkPropertyMetadataOptions.NotDataBindable));
 
        /// 
        ///     ValidationErrors DependencyProperty.
        ///     holds the list of all active validation errors of any data binding targeting the hosting element.
        ///  
        /// 
        ///     The application cannot modify the content of this collection. 
        ///  
        public static readonly DependencyProperty ErrorsProperty =
                ErrorsPropertyKey.DependencyProperty; 

        ///  Static accessor for Validation.Errors property 
        /// 
        ///     The application cannot modify the content of this collection. 
        /// 
        ///  DependencyObject element cannot be null  
        public static ReadOnlyObservableCollection GetErrors(DependencyObject element) 
        {
            if (element == null) 
                throw new ArgumentNullException("element");

            return (ReadOnlyObservableCollection) element.GetValue(ErrorsProperty);
        } 

        ///  
        ///     holds the internally modifiable collection of validation errors. 
        /// 
        internal static readonly DependencyProperty ValidationErrorsInternalProperty = 
                DependencyProperty.RegisterAttached("ErrorsInternal",
                        typeof(ValidationErrorCollection), typeof(Validation),
                        new FrameworkPropertyMetadata(
                                (ValidationErrorCollection)null, 
                                new PropertyChangedCallback(OnErrorsInternalChanged)));
 
        // Update HasErrors and Invalidate the public ValidationErrors property whose GetOverride will return 
        // the updated value of ValidationErrorsInternal, nicely wrapped into a ReadOnlyCollection
        private static void OnErrorsInternalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            ValidationErrorCollection newErrors = e.NewValue as ValidationErrorCollection;

            if (newErrors != null) 
            {
                d.SetValue(ErrorsPropertyKey, new ReadOnlyObservableCollection(newErrors)); 
            } 
            else
            { 
                d.ClearValue(ErrorsPropertyKey);
            }
        }
 
        internal static ValidationErrorCollection GetErrorsInternal(DependencyObject target)
        { 
            return (ValidationErrorCollection) target.GetValue(Validation.ValidationErrorsInternalProperty); 
        }
 
        /// 
        ///     The key needed set a read-only property.
        /// 
        internal static readonly DependencyPropertyKey HasErrorPropertyKey = 
                DependencyProperty.RegisterAttachedReadOnly("HasError",
                        typeof(bool), typeof(Validation), 
                        new FrameworkPropertyMetadata( 
                                BooleanBoxes.FalseBox,
                                FrameworkPropertyMetadataOptions.NotDataBindable)); 

        /// 
        ///     HasError DependencyProperty is true if any binding on the target element
        ///     has a validation error. 
        /// 
        public static readonly DependencyProperty HasErrorProperty= 
            HasErrorPropertyKey.DependencyProperty; 

        ///  Static accessor for HasError property  
        ///  DependencyObject element cannot be null 
        public static bool GetHasError(DependencyObject element)
        {
            if (element == null) 
                throw new ArgumentNullException("element");
 
            return (bool) element.GetValue(HasErrorProperty); 
        }
 
        /// 
        ///     Template used to generate validation error feedback on the AdornerLayer.  Default
        ///     Template is:
        ///  
        ///     
        ///         
        ///      
        /// 
        ///  
        public static readonly DependencyProperty ErrorTemplateProperty =
                DependencyProperty.RegisterAttached("ErrorTemplate",
                            typeof(ControlTemplate), typeof(Validation),
                            new FrameworkPropertyMetadata( 
                                CreateDefaultErrorTemplate(),
                                FrameworkPropertyMetadataOptions.NotDataBindable, 
                                new PropertyChangedCallback(OnErrorTemplateChanged))); 

 
        ///  Static accessor for ErrorTemplate property 
        ///  DependencyObject element cannot be null 
        [AttachedPropertyBrowsableForType(typeof(DependencyObject))]
        public static ControlTemplate GetErrorTemplate(DependencyObject element) 
        {
            if (element == null) 
                throw new ArgumentNullException("element"); 

            return element.GetValue(ErrorTemplateProperty) as ControlTemplate; 
        }

        ///  Static modifier for ErrorTemplate property 
        ///  DependencyObject element cannot be null  
        public static void SetErrorTemplate(DependencyObject element, ControlTemplate value)
        { 
            if (element == null) 
                throw new ArgumentNullException("element");
 
            // (perf) don't set if the existing value is already correct
            object oldValue = element.ReadLocalValue(ErrorTemplateProperty);
            if (!Object.Equals(oldValue, value))
                element.SetValue(ErrorTemplateProperty, value); 
        }
 
        // when ErrorTemplate changes, redraw the currently visible adorner 
        private static void OnErrorTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            if (GetHasError(d))
            {
                ShowValidationAdorner(d, false);
                ShowValidationAdorner(d, true); 
            }
        } 
 

        ///  
        ///     Designates the alternative element to which validation feedback
        ///     should be directed.
        /// 
        public static readonly DependencyProperty ValidationAdornerSiteProperty = 
                DependencyProperty.RegisterAttached("ValidationAdornerSite",
                            typeof(DependencyObject), typeof(Validation), 
                            new FrameworkPropertyMetadata((DependencyObject)null, 
                                                        new PropertyChangedCallback(OnValidationAdornerSiteChanged)));
 

        ///  Static accessor for ValidationAdornerSite property 
        ///  DependencyObject element cannot be null 
        [AttachedPropertyBrowsableForType(typeof(DependencyObject))] 
        public static DependencyObject GetValidationAdornerSite(DependencyObject element)
        { 
            if (element == null) 
                throw new ArgumentNullException("element");
 
            return element.GetValue(ValidationAdornerSiteProperty) as DependencyObject;
        }

        ///  Static modifier for ValidationAdornerSite property  
        ///  DependencyObject element cannot be null 
        public static void SetValidationAdornerSite(DependencyObject element, DependencyObject value) 
        { 
            if (element == null)
                throw new ArgumentNullException("element"); 

            element.SetValue(ValidationAdornerSiteProperty, value);
        }
 
        // when Site property changes, update the SiteFor property on the other end
        private static void OnValidationAdornerSiteChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        { 
            DependencyObject oldSite = (DependencyObject)e.OldValue;
            DependencyObject newSite = (DependencyObject)e.NewValue; 

            if (oldSite != null)
            {
                oldSite.ClearValue(ValidationAdornerSiteForProperty); 
            }
 
            if (newSite != null) 
            {
                if (d != GetValidationAdornerSiteFor(newSite)) 
                {
                    SetValidationAdornerSiteFor(newSite, d);
                }
            } 

            // if the adorner is currently visible, move it to the new site 
            if (GetHasError(d)) 
            {
                if (oldSite == null) 
                {
                    oldSite = d;
                }
                ShowValidationAdornerHelper(d, oldSite, false); 
                ShowValidationAdorner(d, true);
            } 
        } 

 
        /// 
        ///     Designates the element for which the current element should server
        ///     as the .
        ///  
        public static readonly DependencyProperty ValidationAdornerSiteForProperty =
                DependencyProperty.RegisterAttached("ValidationAdornerSiteFor", 
                            typeof(DependencyObject), typeof(Validation), 
                            new FrameworkPropertyMetadata((DependencyObject)null,
                                                        new PropertyChangedCallback(OnValidationAdornerSiteForChanged))); 


        ///  Static accessor for ValidationAdornerSiteFor property 
        ///  DependencyObject element cannot be null  
        [AttachedPropertyBrowsableForType(typeof(DependencyObject))]
        public static DependencyObject GetValidationAdornerSiteFor(DependencyObject element) 
        { 
            if (element == null)
                throw new ArgumentNullException("element"); 

            return element.GetValue(ValidationAdornerSiteForProperty) as DependencyObject;
        }
 
        ///  Static modifier for ValidationAdornerSiteFor property 
        ///  DependencyObject element cannot be null  
        public static void SetValidationAdornerSiteFor(DependencyObject element, DependencyObject value) 
        {
            if (element == null) 
                throw new ArgumentNullException("element");

            element.SetValue(ValidationAdornerSiteForProperty, value);
        } 

        // when SiteFor property changes, update the Site property on the other end 
        private static void OnValidationAdornerSiteForChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            DependencyObject oldSiteFor = (DependencyObject)e.OldValue; 
            DependencyObject newSiteFor = (DependencyObject)e.NewValue;

            if (oldSiteFor != null)
            { 
                oldSiteFor.ClearValue(ValidationAdornerSiteProperty);
            } 
 
            if (newSiteFor != null)
            { 
                if (d != GetValidationAdornerSite(newSiteFor))
                {
                    SetValidationAdornerSite(newSiteFor, d);
                } 
            }
        } 
 

        internal static void ShowValidationAdorner(DependencyObject targetElement, bool show) 
        {
            // redirect the adorner to the designated site, if any
            DependencyObject adornerSite = GetValidationAdornerSite(targetElement);
            if (adornerSite == null) 
            {
                adornerSite = targetElement; 
            } 

            ShowValidationAdornerHelper(targetElement, adornerSite, show); 
        }

        private static void ShowValidationAdornerHelper(DependencyObject targetElement, DependencyObject adornerSite, bool show)
        { 
            UIElement siteUIElement = adornerSite as UIElement;
 
            if (siteUIElement != null) 
            {
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(siteUIElement); 

                if (adornerLayer == null)
                    return;
 
                TemplatedAdorner validationAdorner = siteUIElement.ReadLocalValue(ValidationAdornerProperty) as TemplatedAdorner;
 
                if (show && validationAdorner == null) 
                {
                    // get the template from the site, or from the target element 
                    ControlTemplate validationTemplate = GetErrorTemplate(siteUIElement);
                    if (validationTemplate == null)
                    {
                        validationTemplate = GetErrorTemplate(targetElement); 
                    }
 
                    if (validationTemplate != null) 
                    {
                        validationAdorner = new TemplatedAdorner(siteUIElement, validationTemplate); 
                        adornerLayer.Add(validationAdorner);

                        siteUIElement.SetValue(ValidationAdornerProperty, validationAdorner);
                    } 
                }
                else if (!show && validationAdorner != null) 
                { 
                    validationAdorner.ClearChild();
                    adornerLayer.Remove(validationAdorner); 
                    siteUIElement.ClearValue(ValidationAdornerProperty);
                }
            }
        } 

 
        ///  
        /// Mark this BindingExpression as invalid.  If the BindingExpression has been
        /// explicitly marked invalid in this way, then it will remain 
        /// invalid until ClearInvalid is called or another transfer to the source validates successfully.
        /// 
        public static void MarkInvalid(BindingExpressionBase bindingExpression, ValidationError validationError)
        { 
            if (bindingExpression == null)
                throw new ArgumentNullException("bindingExpression"); 
            if (validationError == null) 
                throw new ArgumentNullException("validationError");
 
            bindingExpression.UpdateValidationError(validationError);
        }

        ///  
        /// Clears the ValidationError that was set through a call
        /// to MarkInvalid or a previously failed validation of that BindingExpression. 
        ///  
        public static void ClearInvalid(BindingExpressionBase bindingExpression)
        { 
            if (bindingExpression == null)
                throw new ArgumentNullException("bindingExpression");
            bindingExpression.UpdateValidationError(null);
        } 

        // add a validation error to the given element 
        internal static void AddValidationError(ValidationError validationError, DependencyObject targetElement, bool shouldRaiseEvent) 
        {
            if (targetElement == null) 
                return;

            bool wasValid;
            ValidationErrorCollection validationErrors = GetErrorsInternal(targetElement); 

            if (validationErrors == null) 
            { 
                wasValid = true;
                validationErrors = new ValidationErrorCollection(); 
                validationErrors.Add(validationError);
                targetElement.SetValue(Validation.ValidationErrorsInternalProperty, validationErrors);
            }
            else 
            {
                wasValid = (validationErrors.Count == 0); 
                validationErrors.Add(validationError); 
            }
 
            if (wasValid)
            {
                targetElement.SetValue(HasErrorPropertyKey, BooleanBoxes.TrueBox);
            } 

            if (shouldRaiseEvent) 
            { 
                OnValidationError(targetElement, validationError, ValidationErrorEventAction.Added);
            } 

            if (wasValid)
            {
                ShowValidationAdorner(targetElement, true); 
            }
        } 
 
        // remove a validation error from the given element
        internal static void RemoveValidationError(ValidationError validationError, DependencyObject targetElement, bool shouldRaiseEvent) 
        {
            if (targetElement == null)
                return;
 
            ValidationErrorCollection validationErrors = GetErrorsInternal(targetElement);
            if (validationErrors == null || validationErrors.Count == 0 || !validationErrors.Contains(validationError)) 
                return; 

            bool isValid = (validationErrors.Count == 1);   // about to remove the last error 

            if (isValid)
            {
                targetElement.ClearValue(HasErrorPropertyKey); 
            }
 
            validationErrors.Remove(validationError); 

            if (shouldRaiseEvent) 
            {
                OnValidationError(targetElement, validationError, ValidationErrorEventAction.Removed);
            }
 
            if (isValid)
            { 
                targetElement.ClearValue(ValidationErrorsInternalProperty); 
                ShowValidationAdorner(targetElement, false);
            } 
        }

        static void OnValidationError(DependencyObject source, ValidationError validationError, ValidationErrorEventAction action)
        { 
            ValidationErrorEventArgs args = new ValidationErrorEventArgs(validationError, action);
 
            if (source is ContentElement) 
                ((ContentElement)source).RaiseEvent(args);
            else if (source is UIElement) 
                ((UIElement)source).RaiseEvent(args);
            else if (source is UIElement3D)
                ((UIElement3D)source).RaiseEvent(args);
        } 

        private static ControlTemplate CreateDefaultErrorTemplate() 
        { 
            ControlTemplate defaultTemplate = new ControlTemplate(typeof(Control));
 
            //
            //        
            //
 
            FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border), "Border");
            border.SetValue(Border.BorderBrushProperty, Brushes.Red); 
            border.SetValue(Border.BorderThicknessProperty, new Thickness(1)); 

            FrameworkElementFactory adornedElementPlaceHolder = new FrameworkElementFactory(typeof(AdornedElementPlaceholder), "Placeholder"); 

            border.AppendChild(adornedElementPlaceHolder);

            defaultTemplate.VisualTree = border; 
            defaultTemplate.Seal();
 
            return defaultTemplate; 
        }
 
        /// 
        ///     Reference to the ValidationAdorner
        /// 
        private static readonly DependencyProperty ValidationAdornerProperty = 
                DependencyProperty.RegisterAttached("ValidationAdorner",
                        typeof(TemplatedAdorner), typeof(Validation), 
                        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.NotDataBindable)); 

    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK