예제 #1
0
        /// <summary>
        /// Load meta data and update the UI.
        /// </summary>
        /// <param name="forceUpdate">If true, metadata will not be loaded from cache.</param>
        private void LoadMetadata(bool forceUpdate)
        {
            ValidationMetadata vmd               = null;
            object             entity            = null;
            BindingExpression  bindingExpression = null;

            if (!String.IsNullOrEmpty(this.PropertyPath))
            {
                entity = this.DataContext;
                // Pull metadata directly from the DataContext.  This isn't cached so it will be pulled every time.
                vmd = ValidationHelper.ParseMetadata(this.PropertyPath, entity);
            }
            else if (this.Target != null)
            {
                // Pull the metadata from the target FrameworkElement.
                vmd = ValidationHelper.ParseMetadata(this.Target, forceUpdate, out entity, out bindingExpression);
            }
            if (this.ValidationMetadata != vmd)
            {
                this.ValidationMetadata = vmd;
                // Update to the new VMD
                if (!this._descriptionOverridden)
                {
                    string description = null;
                    if (this.ValidationMetadata != null)
                    {
                        description = this.ValidationMetadata.Description;
                    }
                    SetValue(DescriptionProperty, description);
                }
            }
        }
        private void Target_BindingValidationError(object sender, ValidationErrorEventArgs e)
        {
            FrameworkElement inputControl = e.OriginalSource as FrameworkElement;

            if (e != null && e.Error != null && e.Error.ErrorContent != null && inputControl != null)
            {
                string message = e.Error.ErrorContent.ToString();
                string key     = String.IsNullOrEmpty(inputControl.Name) ? inputControl.GetHashCode().ToString(CultureInfo.InvariantCulture) : inputControl.Name;
                key += message;
                if (this._validationSummaryItemDictionary.ContainsKey(key))
                {
                    ValidationSummaryItem existingError = this._validationSummaryItemDictionary[key];
                    this._errors.Remove(existingError);
                    this._validationSummaryItemDictionary.Remove(key);
                }
                if (e.Action == ValidationErrorEventAction.Added)
                {
                    if (GetShowErrorsInSummary(inputControl))
                    {
                        // New error
                        string             propertyName = null;
                        object             entity;
                        BindingExpression  be;
                        ValidationMetadata vmd = ValidationHelper.ParseMetadata(inputControl, false, out entity, out be);
                        if (vmd != null)
                        {
                            propertyName = vmd.Caption;
                        }
                        ValidationSummaryItem vsi = new ValidationSummaryItem(message, propertyName, ValidationSummaryItemType.PropertyError, new ValidationSummaryItemSource(propertyName, inputControl as Control), null);
                        this._errors.Add(vsi);
                        this._validationSummaryItemDictionary[key] = vsi;
                    }
                }
            }
        }
        /// <summary>
        /// Parse metadata from a target FrameworkElement.  This will cache the metadata on the element as an attached property.
        /// </summary>
        /// <param name="element">The target FrameworkElement to pull metadata from.</param>
        /// <param name="forceUpdate">If set, will not pull metadata from cache.</param>
        /// <param name="entity">The entity used.</param>
        /// <param name="bindingExpression">The bindingExpression used.</param>
        /// <returns>Returns the metadata associated with the element.  Will be null if no metadata was found.</returns>
        internal static ValidationMetadata ParseMetadata(FrameworkElement element, bool forceUpdate, out object entity, out BindingExpression bindingExpression)
        {
            entity            = null;
            bindingExpression = null;
            if (element == null)
            {
                return(null);
            }

            if (!forceUpdate)
            {
                ValidationMetadata existingVMD = element.GetValue(ValidationMetadataProperty) as ValidationMetadata;
                if (existingVMD != null)
                {
                    return(existingVMD);
                }
            }

            BindingExpression be = null;

            FieldInfo[] fields = element.GetType().GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
            foreach (FieldInfo field in fields)
            {
                if (field.FieldType == typeof(DependencyProperty))
                {
                    // Found a dependency property
                    be = element.GetBindingExpression((DependencyProperty)field.GetValue(null));
                    if (be != null && be.ParentBinding != null && be.ParentBinding.Path != null)
                    {
                        // Found a BindingExpression, ensure it has valid data
                        entity = be.DataItem != null ? be.DataItem : element.DataContext;
                        if (entity != null)
                        {
                            if (be.ParentBinding.Mode == BindingMode.TwoWay)
                            {
                                bindingExpression = be;
                                // A twoway binding will be automatically chosen and the rest ignored
                                break;
                            }

                            // Perform an arbitrary sort on path (string), so the same dependency property is chosen consistently.
                            // Reflection ordering is not deterministic and if we just pick the first, we could be
                            // matched with different dependency properties depending on the run.
                            if (bindingExpression == null || string.Compare(be.ParentBinding.Path.Path, bindingExpression.ParentBinding.Path.Path, StringComparison.Ordinal) < 0)
                            {
                                bindingExpression = be;
                            }
                        }
                    }
                }
            }
            if (bindingExpression != null)
            {
                ValidationMetadata newVMD = ParseMetadata(bindingExpression.ParentBinding.Path.Path, entity);
                element.SetValue(ValidationMetadataProperty, newVMD);
                return(newVMD);
            }
            return(null);
        }
 /// <summary>
 /// Sets the ValidationMetadata property for the input control
 /// </summary>
 /// <param name="inputControl">The input control to set the ValidationMetadata property on.</param>
 /// <param name="value">The ValidationMetadata to associate with the input control.</param>
 internal static void SetValidationMetadata(DependencyObject inputControl, ValidationMetadata value)
 {
     if (inputControl == null)
     {
         throw new ArgumentNullException("inputControl");
     }
     inputControl.SetValue(ValidationMetadataProperty, value);
 }
        /// <summary>
        /// Parse metadata given a binding path and entity object.
        /// </summary>
        /// <param name="bindingPath">The bindingPath is the name of the property on the entity from which to pull metadata from.  This supports dot notation.</param>
        /// <param name="entity">The entity object from which to pull metadata from.</param>
        /// <returns>The validation metadata associated with the entity and binding path.  This will return null if none exists.</returns>
        internal static ValidationMetadata ParseMetadata(string bindingPath, object entity)
        {
            if (entity != null && !String.IsNullOrEmpty(bindingPath))
            {
                Type         entityType = entity.GetType();
                PropertyInfo prop       = GetProperty(entityType, bindingPath);
                if (prop != null)
                {
                    ValidationMetadata newVMD     = new ValidationMetadata();
                    object[]           attributes = prop.GetCustomAttributes(false);
                    foreach (object propertyAttribute in attributes)
                    {
                        // Loop through each attribute and update the VMD as appropriate

                        // RequiredField
                        RequiredAttribute reqAttribute = propertyAttribute as RequiredAttribute;
                        if (reqAttribute != null)
                        {
                            newVMD.IsRequired = true;
                            continue;
                        }

                        // Display attribute parsing
                        DisplayAttribute displayAttribute = propertyAttribute as DisplayAttribute;
                        if (displayAttribute != null)
                        {
                            newVMD.Description = displayAttribute.GetDescription();
                            newVMD.Caption     = displayAttribute.GetName();
                            continue;
                        }
                    }
                    if (newVMD.Caption == null)
                    {
                        // If the name is not defined via the DisplayAttribute, use the property name.
                        newVMD.Caption = prop.Name;

                        // Caption can be set to empty string to have an empty Caption and not default
                        // to the property name.
                    }

                    return(newVMD);
                }
            }
            return(null);
        }
예제 #6
0
        /// <summary>
        /// Load meta data and update the UI.
        /// </summary>
        /// <param name="forceUpdate">If true, metadata will not be loaded from cache.</param>
        private void LoadMetadata(bool forceUpdate)
        {
            ValidationMetadata vmd               = null;
            object             entity            = null;
            BindingExpression  bindingExpression = null;

            if (!String.IsNullOrEmpty(this.PropertyPath))
            {
                entity = this.DataContext;
                // Pull metadata directly from the DataContext.  This isn't cached so it will be pulled every time.
                vmd = ValidationHelper.ParseMetadata(this.PropertyPath, entity);
            }
            else if (this.Target != null)
            {
                // Pull the metadata from the target FrameworkElement.
                vmd = ValidationHelper.ParseMetadata(this.Target, forceUpdate, out entity, out bindingExpression);
            }
            if (this.ValidationMetadata != vmd)
            {
                this.ValidationMetadata = vmd;
                // Update to the new VMD
                if (this.ValidationMetadata != null)
                {
                    string newContent = this.ValidationMetadata.Caption;
                    if (newContent != null && this._canContentUseMetaData)
                    {
                        this.SetContentInternally(newContent);
                    }
                }
                else if (this._canContentUseMetaData)
                {
                    // The Target property was reset. Since the Content property
                    // was using the metadata, it also needs to be reset.
                    this.SetContentInternally(null);
                }

                if (!this._isRequiredOverridden)
                {
                    bool isRequired = this.ValidationMetadata == null ? false : this.ValidationMetadata.IsRequired;
                    SetValue(Label.IsRequiredProperty, isRequired);
                }
            }
        }
예제 #7
0
        /// <summary>
        /// Load meta data and update the UI.
        /// </summary>
        /// <param name="forceUpdate">If true, metadata will not be loaded from cache.</param>
        private void LoadMetadata(bool forceUpdate)
        {
            ValidationMetadata vmd               = null;
            object             entity            = null;
            BindingExpression  bindingExpression = null;

            if (!String.IsNullOrEmpty(this.PropertyPath))
            {
                entity = this.DataContext;
                // Pull metadata directly from the DataContext.  This isn't cached so it will be pulled every time.
                vmd = ValidationHelper.ParseMetadata(this.PropertyPath, entity);
            }
            else if (this.Target != null)
            {
                // Pull the metadata from the target FrameworkElement.
                vmd = ValidationHelper.ParseMetadata(this.Target, forceUpdate, out entity, out bindingExpression);
            }
            if (this.ValidationMetadata != vmd)
            {
                this.ValidationMetadata = vmd;
                // Update to the new VMD

                string newContent = null;
                if (this.ValidationMetadata != null)
                {
                    newContent = this.ValidationMetadata.Caption;
                }
                SetValue(Label.ContentInternalProperty, newContent);

                if (!this._isRequiredOverridden)
                {
                    bool isRequired = this.ValidationMetadata == null ? false : this.ValidationMetadata.IsRequired;
                    SetValue(Label.IsRequiredProperty, isRequired);
                }
            }
        }
 /// <summary>
 /// Sets the ValidationMetadata property for the input control
 /// </summary>
 /// <param name="inputControl">The input control to set the ValidationMetadata property on.</param>
 /// <param name="value">The ValidationMetadata to associate with the input control.</param>
 internal static void SetValidationMetadata(DependencyObject inputControl, ValidationMetadata value)
 {
     if (inputControl == null)
     {
         throw new ArgumentNullException("inputControl");
     }
     inputControl.SetValue(ValidationMetadataProperty, value);
 }
        /// <summary>
        /// Parse metadata given a binding path and entity object.
        /// </summary>
        /// <param name="bindingPath">The bindingPath is the name of the property on the entity from which to pull metadata from.  This supports dot notation.</param>
        /// <param name="entity">The entity object from which to pull metadata from.</param>
        /// <returns>The validation metadata associated with the entity and binding path.  This will return null if none exists.</returns>
        internal static ValidationMetadata ParseMetadata(string bindingPath, object entity)
        {
            if (entity != null && !String.IsNullOrEmpty(bindingPath))
            {
                Type entityType = entity.GetType();
                PropertyInfo prop = GetProperty(entityType, bindingPath);
                if (prop != null)
                {
                    ValidationMetadata newVMD = new ValidationMetadata();
                    object[] attributes = prop.GetCustomAttributes(false);
                    foreach (object propertyAttribute in attributes)
                    {
                        // Loop through each attribute and update the VMD as appropriate

                        // RequiredField
                        RequiredAttribute reqAttribute = propertyAttribute as RequiredAttribute;
                        if (reqAttribute != null)
                        {
                            newVMD.IsRequired = true;
                            continue;
                        }

                        // Display attribute parsing
                        DisplayAttribute displayAttribute = propertyAttribute as DisplayAttribute;
                        if (displayAttribute != null)
                        {
                            newVMD.Description = displayAttribute.GetDescription();
                            newVMD.Caption = displayAttribute.GetName();
                            continue;
                        }
                    }
                    if (newVMD.Caption == null)
                    {
                        // If the name is not defined via the DisplayAttribute, use the property name.
                        newVMD.Caption = prop.Name;

                        // Caption can be set to empty string to have an empty Caption and not default
                        // to the property name.
                    }

                    return newVMD;
                }
            }
            return null;
        }
예제 #10
0
        /// <summary>
        /// Load meta data and update the UI. 
        /// </summary>
        /// <param name="forceUpdate">If true, metadata will not be loaded from cache.</param>
        private void LoadMetadata(bool forceUpdate)
        {
            ValidationMetadata vmd = null;
            object entity = null;
            BindingExpression bindingExpression = null;
            if (!String.IsNullOrEmpty(this.PropertyPath))
            {
                entity = this.DataContext;
                // Pull metadata directly from the DataContext.  This isn't cached so it will be pulled every time.
                vmd = ValidationHelper.ParseMetadata(this.PropertyPath, entity);
            }
            else if (this.Target != null)
            {
                // Pull the metadata from the target FrameworkElement.
                vmd = ValidationHelper.ParseMetadata(this.Target, forceUpdate, out entity, out bindingExpression);
            }
            if (this.ValidationMetadata != vmd)
            {
                this.ValidationMetadata = vmd;
                // Update to the new VMD
                if (this.ValidationMetadata != null)
                {
                    string newContent = this.ValidationMetadata.Caption;
                    if (newContent != null && this._canContentUseMetaData)
                    {
                        this.SetContentInternally(newContent);
                    }
                }
                else if (this._canContentUseMetaData)
                {
                    // The Target property was reset. Since the Content property
                    // was using the metadata, it also needs to be reset.
                    this.SetContentInternally(null);
                }

                if (!this._isRequiredOverridden)
                {
                    bool isRequired = this.ValidationMetadata == null ? false : this.ValidationMetadata.IsRequired;
                    SetValue(Label.IsRequiredProperty, isRequired);
                }
            }
        }