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); } } }