private IEnumerable <KeyValuePair <Guid, string> > ValidateRequiredCache()
        {
            if (_fields == null)
            {
                _fields = new List <UIElement>();
                CacheTree(this);
            }

            return(_fields.Where(x => !CheckIfFilledIn(x))
                   .Select(x => new KeyValuePair <Guid, string>(NovaValidation.GetEntityID(x), NovaValidation.GetFieldName(x)))
                   .ToList());
        }
        private static bool CheckIfFilledIn(UIElement element)
        {
            if (element == null)
            {
                return(true);
            }

            if (ViewMode.GetIsReadOnly(element)) //Read Only elements can't be required.
            {
                return(true);
            }

            if (!NovaValidation.GetIsRequired(element))
            {
                return(true);
            }

            var textbox = element as TextBox;

            if (textbox != null)
            {
                return(!string.IsNullOrEmpty(textbox.Text));
            }

            var combobox = element as ComboBox;

            if (combobox != null)
            {
                return(!string.IsNullOrEmpty(combobox.Text));
            }

            var passwordBox = element as PasswordBox;

            if (passwordBox != null)
            {
                return(PasswordBoxMonitor.IsFilledIn(passwordBox));
            }

            var validationBorder = element as ValidationBorder;

            if (validationBorder != null)
            {
                return(validationBorder.IsFilledIn);
            }

            return(true); //return true if we don't know what it is, so we don't block anything because of possibly faulty validation.
        }
        /// <summary>
        /// Caches the fields.
        /// </summary>
        /// <param name="dependencyObject">The dependency object.</param>
        /// <param name="fields">The fields dictionary used for caching.</param>
        private static void CacheLogicalTree(DependencyObject dependencyObject, ICollection <UIElement> fields)
        {
            foreach (var child in LogicalTreeHelper.GetChildren(dependencyObject).OfType <DependencyObject>())
            {
                var uiElement = child as UIElement;
                if (uiElement != null)
                {
                    var fieldName = NovaValidation.GetFieldName(child);
                    if (!string.IsNullOrEmpty(fieldName))
                    {
                        fields.Add(uiElement);
                    }
                }

                CacheLogicalTree(child, fields);
            }
        }
        private IEnumerable <KeyValuePair <Guid, string> > ValidateRequiredLogicalTree(DependencyObject dependencyObject)
        {
            var fields = new List <KeyValuePair <Guid, string> >();

            foreach (var child in LogicalTreeHelper.GetChildren(dependencyObject).OfType <DependencyObject>())
            {
                if (!CheckIfFilledIn(child as UIElement))
                {
                    var entityID = NovaValidation.GetEntityID(child);
                    var field    = NovaValidation.GetFieldName(child);
                    var kvp      = new KeyValuePair <Guid, string>(entityID, field);
                    fields.Add(kvp);
                }

                fields = fields.Union(ValidateRequiredLogicalTree(child)).ToList();
            }

            return(fields);
        }
        /// <summary>
        /// Caches the fields.
        /// </summary>
        /// <param name="dependencyObject">The dependency object.</param>
        /// <param name="fields">The fields dictionary used for caching.</param>
        private static void CacheVisualTree(DependencyObject dependencyObject, ICollection <UIElement> fields)
        {
            var count = VisualTreeHelper.GetChildrenCount(dependencyObject);

            for (var i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(dependencyObject, i);

                var uiElement = child as UIElement;
                if (uiElement != null)
                {
                    var fieldName = NovaValidation.GetFieldName(child);
                    if (!string.IsNullOrEmpty(fieldName))
                    {
                        fields.Add(uiElement);
                    }
                }

                CacheVisualTree(child, fields);
            }
        }
        private IEnumerable <KeyValuePair <Guid, string> > ValidateRequiredVisualTree(DependencyObject dependencyObject)
        {
            var count  = VisualTreeHelper.GetChildrenCount(dependencyObject);
            var fields = new List <KeyValuePair <Guid, string> >();

            for (var i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(dependencyObject, i);

                if (!CheckIfFilledIn(child as UIElement))
                {
                    var entityID = NovaValidation.GetEntityID(child);
                    var field    = NovaValidation.GetFieldName(child);

                    var kvp = new KeyValuePair <Guid, string>(entityID, field);
                    fields.Add(kvp);
                }

                fields = fields.Union(ValidateRequiredVisualTree(child)).ToList();
            }

            return(fields);
        }
        /// <summary>
        /// Validates the specified element.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="errors">The errors.</param>
        private static void Validate(UIElement element, ReadOnlyErrorCollection errors)
        {
            if (element == null)
            {
                return;
            }

            var field = NovaValidation.GetFieldName(element);

            if (string.IsNullOrEmpty(field))
            {
                return;
            }

            if (errors != null)
            {
                var entityID = NovaValidation.GetEntityID(element);

                var validations = errors.GetValidations(field, entityID).ToList();
                if (validations.Count > 0)
                {
                    NovaValidation.SetIsValid(element, false);

                    //Don't get max ranking/put bullets in front of lines when there is only one message to show.
                    if (validations.Count == 1)
                    {
                        var validation = validations.First();

                        NovaValidation.SetValidationTooltip(element, validation.Message);
                        NovaValidation.SetSeverity(element, validation.SeverityBrush);

                        return;
                    }

                    var mostSevereValidationRanking = validations.Max(x => x.Severity);
                    var mostSevereValidation        = validations.First(x => x.Severity == mostSevereValidationRanking);

                    NovaValidation.SetSeverity(element, mostSevereValidation.SeverityBrush);

                    //Since we are showing the most severe brush, show the most severe messages first as well.
                    validations = validations.OrderByDescending(x => x.Severity).ToList();

                    if (NovaValidation.GetConcatToolTip(element))
                    {
                        var builder = new StringBuilder();

                        for (int index = 0; index < validations.Count; index++)
                        {
                            var validation = validations[index];
                            builder.Append("• ").Append(validation.Message);

                            if (index + 1 < validations.Count)
                            {
                                builder.AppendLine();
                            }
                        }

                        NovaValidation.SetValidationTooltip(element, builder.ToString());
                    }
                    else
                    {
                        NovaValidation.SetValidationTooltip(element, mostSevereValidation.Message);
                    }

                    return;
                }
            }

            NovaValidation.SetIsValid(element, true);
            NovaValidation.SetValidationTooltip(element, null);
        }