递归地查找可视子对象并不是在WPF中添加根对象

本文关键字:对象 WPF 添加 并不是 查找 可视 递归 | 更新日期: 2023-09-27 18:15:37

我有以下实现来获得类型为T的VisualTree中的所有子节点:

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

我用下面的代码调用这个方法:

IEnumerable<TextBlock> textBlocks = FindVisualChildren<TextBlock>(
    button.Content as DependencyObject);

但是,当根依赖对象是t类型时,这个实现不能很好地工作。想象一下,我们想在VisualTree

中找到所有的textblock。
Content
  StackPanel
      TextBlock
      Image

在本例中,实现成功地找到了TextBlock。但是,如果我有另一个布局:

Content
    TextBlock

实现不包括根对象,所以它找不到TextBlock。如何重写方法并包含根对象?

递归地查找可视子对象并不是在WPF中添加根对象

我需要在循环之前生成返回根。这个实现修复了:

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