WPF - 获取页面上给定类型的所有控件的集合?

时间:2011-08-22 20:31:22

标签: c# wpf controls find

我正在尝试获取给定页面上给定类型的所有控件的列表,但我遇到了问题。似乎VisualTreeHelper可能只返回已加载的控件?我尝试关闭虚拟化,但这似乎没有帮助。任何人都可以想到另一种方法来获得所有控制权或强制加载UI以便以下方法有效吗?

我从MSDN借用了这个:

 public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);

                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }

                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }

1 个答案:

答案 0 :(得分:10)

请参阅以下主题:Finding all controls of a given type across a TabControl

Tao Liang 的答案是一个很好的解释

  

原因是WPF设计师希望优化性能   TabControl。假设有5个TabItem,每个TabItem包含   很多孩子。如果WPF程序必须构造并呈现所有   孩子们,会很慢。但是如果TabControl只处理了   孩子只是在当前选中的TabItem中,会有很多内存   保存。

您可以尝试使用逻辑树 以下是此示例实现,看看它是否适合您

像这样使用..

List<Button> buttons = GetLogicalChildCollection<Button>(yourPage);

GetLogicalChildCollection

public static List<T> GetLogicalChildCollection<T>(object parent) where T : DependencyObject
{
    List<T> logicalCollection = new List<T>();
    GetLogicalChildCollection(parent as DependencyObject, logicalCollection);
    return logicalCollection;
}
private static void GetLogicalChildCollection<T>(DependencyObject parent, List<T> logicalCollection) where T : DependencyObject
{
    IEnumerable children = LogicalTreeHelper.GetChildren(parent);
    foreach (object child in children)
    {
        if (child is DependencyObject)
        {
            DependencyObject depChild = child as DependencyObject;
            if (child is T)
            {
                logicalCollection.Add(child as T);
            }
            GetLogicalChildCollection(depChild, logicalCollection);
        }
    }
}