Find all controls in WPF Window by type

后端 未结 17 1215
春和景丽
春和景丽 2020-11-21 10:14

I\'m looking for a way to find all controls on Window by their type,

for example: find all TextBoxes, find all controls implementing specific i

相关标签:
17条回答
  • 2020-11-21 10:48

    And this is how it works upwards

        private T FindParent<T>(DependencyObject item, Type StopAt) where T : class
        {
            if (item is T)
            {
                return item as T;
            }
            else
            {
                DependencyObject _parent = VisualTreeHelper.GetParent(item);
                if (_parent == null)
                {
                    return default(T);
                }
                else
                {
                    Type _type = _parent.GetType();
                    if (StopAt != null)
                    {
                        if ((_type.IsSubclassOf(StopAt) == true) || (_type == StopAt))
                        {
                            return null;
                        }
                    }
    
                    if ((_type.IsSubclassOf(typeof(T)) == true) || (_type == typeof(T)))
                    {
                        return _parent as T;
                    }
                    else
                    {
                        return FindParent<T>(_parent, StopAt);
                    }
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-21 10:49

    I found it easier without Visual Tree Helpers:

    foreach (UIElement element in MainWindow.Children) {
        if (element is TextBox) { 
            if ((element as TextBox).Text != "")
            {
                //Do something
            }
        }
    };
    
    0 讨论(0)
  • 2020-11-21 10:50

    Do note that using the VisualTreeHelper does only work on controls that derive from Visual or Visual3D. If you also need to inspect other elements (e.g. TextBlock, FlowDocument etc.), using VisualTreeHelper will throw an exception.

    Here's an alternative that falls back to the logical tree if necessary:

    http://www.hardcodet.net/2009/06/finding-elements-in-wpf-tree-both-ways

    0 讨论(0)
  • 2020-11-21 10:51

    The accepted answer returns the discovered elements more or less unordered, by following the first child branch as deep as possible, while yielding the discovered elements along the way, before backtracking and repeating the steps for not yet parsed tree branches.

    If you need the descendent elements in descending order, where the direct children will be yielded first, then their children and so on, the following algorithm will work:

    public static IEnumerable<T> GetVisualDescendants<T>(DependencyObject parent, bool applyTemplates = false)
        where T : DependencyObject
    {
        if (parent == null || !(child is Visual || child is Visual3D))
            yield break;
    
        var descendants = new Queue<DependencyObject>();
        descendants.Enqueue(parent);
    
        while (descendants.Count > 0)
        {
            var currentDescendant = descendants.Dequeue();
    
            if (applyTemplates)
                (currentDescendant as FrameworkElement)?.ApplyTemplate();
    
            for (var i = 0; i < VisualTreeHelper.GetChildrenCount(currentDescendant); i++)
            {
                var child = VisualTreeHelper.GetChild(currentDescendant, i);
    
                if (child is Visual || child is Visual3D)
                    descendants.Enqueue(child);
    
                if (child is T foundObject)
                    yield return foundObject;
            }
        }
    }
    

    The resulting elements will be ordered from nearest to farthest. This will be useful e.g. if you are looking for the nearest child element of some type and condition:

    var foundElement = GetDescendants<StackPanel>(someElement)
                           .FirstOrDefault(o => o.SomeProperty == SomeState);
    
    0 讨论(0)
  • 2020-11-21 10:55

    This is the easiest way:

    IEnumerable<myType> collection = control.Children.OfType<myType>(); 
    

    where control is the root element of the window.

    0 讨论(0)
提交回复
热议问题