0

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
Daniel Peñalba
  • 30,507
  • 32
  • 137
  • 219

1 Answers1

2

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;
            }
        }
    }
Daniel Peñalba
  • 30,507
  • 32
  • 137
  • 219