|
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ValidationHelper.cs" company="Catel development team">
// Copyright (c) 2008 - 2011 Catel development team. All rights reserved.
// </copyright>
// <summary>
// Validation helper class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
namespace Catel.Windows.Windows
{
/// <summary>
/// Validation helper class.
/// </summary>
/// <remarks>
/// This code is based on the code that can be found at:
/// http://www.primordialcode.com/index.php/2009/08/19/wpf-force-validation-rules-attached-object-executed/.
/// </remarks>
public static class ValidationHelper
{
#region Variables
private static readonly Dictionary<Type, List<DependencyProperty>> _propertiesReflectionCache = new Dictionary<Type, List<DependencyProperty>>();
#endregion
/// <summary>
/// Gets the dependency properties of a specific type.
/// </summary>
/// <param name="type">The type.</param>
/// <returns><see cref="List{DependencyProperty}"/> containing all the found dependency properties.</returns>
/// <exception cref="ArgumentNullException">when <paramref name="type"/> is <c>null</c>.</exception>
private static List<DependencyProperty> GetDependencyProperties(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
if (_propertiesReflectionCache.ContainsKey(type))
{
return _propertiesReflectionCache[type];
}
FieldInfo[] properties = type.GetFields(BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.FlattenHierarchy);
// We cycle and store only the dependency properties
List<DependencyProperty> dps = (from field in properties
where field.FieldType == typeof(DependencyProperty)
select (DependencyProperty)field.GetValue(null)).ToList();
_propertiesReflectionCache.Add(type, dps);
return dps;
}
/// <summary>
/// Updates the bindings validation. Sometimes, WPF doesn't show the validation red border
/// when validation occurs too soon. This method will force all bound properties to revalidate.
/// </summary>
/// <param name="dependencyObject">The dependency object.</param>
/// <exception cref="ArgumentNullException">when <paramref name="dependencyObject"/> is <c>null</c>.</exception>
public static void UpdateBindingsValidation(DependencyObject dependencyObject)
{
if (dependencyObject == null)
{
throw new ArgumentNullException("dependencyObject");
}
// Get the list of all the dependency properties, we can use a level of caching to avoid to use reflection
// more than one time for each object
foreach (DependencyProperty dp in GetDependencyProperties(dependencyObject.GetType()))
{
if (BindingOperations.IsDataBound(dependencyObject, dp))
{
Binding binding = BindingOperations.GetBinding(dependencyObject, dp);
BindingExpression expression = BindingOperations.GetBindingExpression(dependencyObject, dp);
switch (binding.Mode)
{
case BindingMode.OneTime:
case BindingMode.OneWay:
expression.UpdateTarget();
break;
default:
expression.UpdateSource();
break;
}
}
}
for (int i = 0; i != VisualTreeHelper.GetChildrenCount(dependencyObject); ++i)
{
DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
UpdateBindingsValidation(child);
}
foreach (object child in LogicalTreeHelper.GetChildren(dependencyObject))
{
if (child is UIElement)
{
UpdateBindingsValidation((UIElement)child);
}
}
}
}
}
|
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.