且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-12-06 09:58:22

请参阅以下主题:



陶亮的回答是一个很好的解释 p>


原因是WPF设计者想要优化TabControl的性能
。假设有5个TabItems,并且每个TabItem都包含
的许多子节点。如果WPF程序必须构建和渲染所有
的孩子,那么将会非常缓慢。但是,如果TabControl只处理当前选定的TabItem中的
子元素,那么内存将会被
保存。

你可以给逻辑树一个试试。

这里是一个示例实现,看看它是否更适合你



像这样使用它。

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

GetLogicalChildCollection

  public static List< T> GetLogicalChildCollection< T>(object parent)其中T:DependencyObject 
{
List< T> logicalCollection = new List< T>();
GetLogicalChildCollection(父为DependencyObject,logicalCollection);
返回logicalCollection;

private static void GetLogicalChildCollection< T>(DependencyObject parent,List< T> logicalCollection)其中T:DependencyObject
{
IEnumerable children = LogicalTreeHelper.GetChildren(parent);
foreach(对象子对象)
{
if(child是DependencyObject)
{
DependencyObject depChild = child作为DependencyObject;
if(child is T)
{
logicalCollection.Add(child as T);
}
GetLogicalChildCollection(depChild,logicalCollection);
}
}
}


I'm trying to get a list of all controls of a given type on a given Page, but I'm encountering problems. It seems that it's possible that the VisualTreeHelper only returns controls that have been loaded? I tried turning off Virtualization, but that didn't seem to help. Can anyone think of another way to get all the control or perhaps force a load of the UI so that the following method does work?

I borrowed this from 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;
                    }
                }
            }
        }

See the following thread: Finding all controls of a given type across a TabControl

The answer from Tao Liang is a good explanation

The reason is that the WPF designer want to optimize the performance of TabControl. Suppose there are 5 TabItems, and each TabItem contains alot of children. If WPF program have to construct and render all the children, it will be very slow. But if TabControl only handle the children just in the current selected TabItem, much memory will be saved.

You can give the logical tree a try instead.
Here is an example implementation of this, see if it works better for you

Use it like this..

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