I have the following implementation to get all the children in a VisualTree of a type T:
IEnumerable<T> FindVisualChildrenRecurse<T>(DependencyObject root) where T : DependencyObject
{
if (root != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(root, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildrenRecurse<T>(child))
{
yield return childOfChild;
}
}
}
}
I call this method using the following:
IEnumerable<TextBlock> textBlocks = FindVisualChildren<TextBlock>(
button.Content as DependencyObject);
However, this implementation does not work fine when the root dependendy object is of type T. Imagine that we want to find all TextBlocks in a VisualTree
Content
StackPanel
TextBlock
Image
In this case, the implementation finds successfully the TextBlock. However, if I have this other layout:
Content
TextBlock
The implementation does not include the root object, so it does not find the TextBlock. How can I re-write the method and include the root object?
I needed to yield return the root before looping. This implementation makes the fix:
IEnumerable<T> FindVisualChildren<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject == null)
yield break;
if (dependencyObject is T)
yield return (T)dependencyObject;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}