using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Media;
namespace Developpez.Dotnet.Windows
{
///
/// Fournit des méthodes d'extension pour les DependencyObjects
///
public static class DependencyObjectExtensions
{
///
/// Renvoie un wrapper fortement typé d'un DependencyPropertyChangedEventArgs, qui expose les propriétés
/// OldValue et NewValue de façon fortement typée
///
/// Le type de la propriété
/// Le DependencyPropertyChangedEventArgs à wrapper
/// Un wrapper fortement typé pour les données de l'évènement
public static DependencyPropertyChangedEventArgs OfType(this DependencyPropertyChangedEventArgs args)
{
return new DependencyPropertyChangedEventArgs(args);
}
///
/// Renvoie la valeur de la DependencyProperty spécifiée pour cet objet, en la convertissant dans le type souhaité
///
/// Le type de retour souhaité
/// Le DependencyObject dont on veut obtenir une valeur de propriété
/// La DependencyProperty dont on veut obtenir la valeur pour cet objet
/// La valeur de la propriété pour cet objet
public static T GetValue(this DependencyObject obj, DependencyProperty dp)
{
return (T)obj.GetValue(dp);
}
///
/// Renvoie le parent de l'objet courant dans l'arbre logique
///
/// L'objet dont on veut obtenir le parent
/// Le parent de l'objet dans l'arbre logique
public static DependencyObject GetLogicalParent(this DependencyObject obj)
{
return LogicalTreeHelper.GetParent(obj);
}
///
/// Renvoie les enfants de l'objet courant dans l'arbre logique
///
/// L'objet dont on veut obtenir les enfants
/// Les enfants de l'objet dans l'arbre logique
public static IEnumerable GetLogicalChildren(this DependencyObject obj)
{
return LogicalTreeHelper.GetChildren(obj).Cast();
}
///
/// Renvoie le parent de l'objet courant dans l'arbre visuel
///
/// L'objet dont on veut obtenir le parent
/// Le parent de l'objet dans l'arbre visuel
public static DependencyObject GetVisualParent(this DependencyObject obj)
{
return VisualTreeHelper.GetParent(obj);
}
///
/// Renvoie les enfants de l'objet courant dans l'arbre visuel
///
/// L'objet dont on veut obtenir les enfants
/// Les enfants de l'objet dans l'arbre visuel
public static IEnumerable GetVisualChildren(this DependencyObject obj)
{
int count = VisualTreeHelper.GetChildrenCount(obj);
for (int i = 0; i < count; i++)
{
yield return VisualTreeHelper.GetChild(obj, i);
}
}
///
/// Remonte l'arbre visuel à la recherche d'un parent du type spécifié
///
/// Le type du parent recherché
/// L'objet dont on cherche le parent
/// Le premier parent du type spécifié rencontré, ou null si un tel parent n'existe pas
public static T FindAncestor(this DependencyObject obj) where T : DependencyObject
{
var tmp = VisualTreeHelper.GetParent(obj);
while (tmp != null && !(tmp is T))
{
tmp = VisualTreeHelper.GetParent(tmp);
}
return tmp as T;
}
///
/// Remonte l'arbre visuel à la recherche d'un parent du type spécifié
///
/// L'objet dont on cherche le parent
/// Le type du parent recherché
/// Le premier parent du type spécifié rencontré, ou null si un tel parent n'existe pas
public static DependencyObject FindAncestor(this DependencyObject obj, Type ancestorType)
{
var tmp = VisualTreeHelper.GetParent(obj);
while (tmp != null && !ancestorType.IsAssignableFrom(tmp.GetType()))
{
tmp = VisualTreeHelper.GetParent(tmp);
}
return tmp;
}
///
/// Parcours l'arbre visuel d'un élément et renvoie tous ses descendants du type spécifié.
///
/// Type des descendants recherchés
/// Elément à partir duquel effectuer la recherche
/// Séquence de descendants du type spécifié
public static IEnumerable FindDescendants(this DependencyObject obj) where T : DependencyObject
{
var queue = new Queue(obj.GetVisualChildren());
while (queue.Count > 0)
{
var child = queue.Dequeue();
if (child is T)
yield return (T)child;
foreach (var c in child.GetVisualChildren())
{
queue.Enqueue(c);
}
}
}
///
/// Parcours l'arbre visuel d'un élément et renvoie tous ses descendants du type spécifié.
///
/// Elément à partir duquel effectuer la recherche
/// Type des descendants recherchés
/// Séquence de descendants du type spécifié
public static IEnumerable FindDescendants(this DependencyObject obj, Type descendantType)
{
var queue = new Queue(obj.GetVisualChildren());
while (queue.Count > 0)
{
var child = queue.Dequeue();
if (descendantType.IsAssignableFrom(child.GetType()))
yield return child;
foreach (var c in child.GetVisualChildren())
{
queue.Enqueue(c);
}
}
}
///
/// Ajoute un handler pour être notifié du changement de la DependencyProperty spécifiée
///
/// L'objet à surveiller
/// La propriété à surveiller
/// Le handler à appeler quand la valeur de la propriété change
public static void AddPropertyChangedHandler(this DependencyObject obj, DependencyProperty property, EventHandler handler)
{
var desc = DependencyPropertyDescriptor.FromProperty(property, obj.GetType());
desc.AddValueChanged(obj, handler);
}
///
/// Supprime un handler de notification de changement de DependencyProperty
///
/// L'objet qui possède la propriété
/// La propriété
/// Le handler à supprimer
public static void RemovePropertyChangedHandler(this DependencyObject obj, DependencyProperty property, EventHandler handler)
{
var desc = DependencyPropertyDescriptor.FromProperty(property, obj.GetType());
desc.RemoveValueChanged(obj, handler);
}
}
}