using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
namespace DJ.Extensions
{
public static class DependencyObjectExtensions
{
///
/// Analyzes both visual and logical tree in order to find all elements of a given
/// type that are descendants of the item.
///
/// The type of the queried items.
/// The root element that marks the source of the search. If the
/// source is already of the requested type, it will not be included in the result.
/// The UID of the
/// All descendants of that match the requested type.
public static T FindChildByUid(this DependencyObject source, string uid) where T : UIElement
{
if (source != null)
{
var childs = GetChildObjects(source);
foreach (DependencyObject child in childs)
{
//analyze if children match the requested type
if (child != null && child is T dependencyObject && dependencyObject.Uid.Equals(uid))
{
return dependencyObject;
}
var descendant = FindChildByUid(child, uid);
if (descendant != null)
return descendant;
}
}
return null;
}
///
/// This method is an alternative to WPF's
/// method, which also
/// supports content elements. Keep in mind that for content elements,
/// this method falls back to the logical tree of the element.
///
/// The item to be processed.
/// The submitted item's child elements, if available.
public static IEnumerable GetChildObjects(this DependencyObject parent)
{
if (parent == null) yield break;
if (parent is ContentElement || parent is FrameworkElement)
{
//use the logical tree for content / framework elements
foreach (object obj in LogicalTreeHelper.GetChildren(parent))
{
var depObj = obj as DependencyObject;
if (depObj != null) yield return (DependencyObject) obj;
}
}
else
{
//use the visual tree per default
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
yield return VisualTreeHelper.GetChild(parent, i);
}
}
}
}
}