Find all TextBox controls in UWP Page

2019-06-20 11:07发布

问题:

I need to find all TextBox(es) that are on a UWP Page but having no luck. I thought it would be a simple foreach on Page.Controls but this does not exist.

Using DEBUG I am able to see, for example, a Grid. But I have to first cast the Page.Content to Grid before I can see the Children collection. I do not want to do this as it may not be a Grid at the root of the page.

Thank you in advance.

UPDATE: This is not the same as 'Find all controls in WPF Window by type'. That is WPF. This is UWP. They are different.

回答1:

You're almost there! Cast the Page.Content to UIElementCollection, that way you can get the Children collection and be generic.

You'll have to make your method recurse and look either for Content property if element is a UIElement or Children if element is UIElementCollection.

Here's an example:

    void FindTextBoxex(object uiElement, IList<TextBox> foundOnes)
    {
        if (uiElement is TextBox)
        {
            foundOnes.Add((TextBox)uiElement);
        }
        else if (uiElement is Panel)
        {
            var uiElementAsCollection = (Panel)uiElement;
            foreach (var element in uiElementAsCollection.Children)
            {
                FindTextBoxex(element, foundOnes);
            }
        }
        else if (uiElement is UserControl)
        {
            var uiElementAsUserControl = (UserControl)uiElement;
            FindTextBoxex(uiElementAsUserControl.Content, foundOnes);
        }
        else if (uiElement is ContentControl)
        {
            var uiElementAsContentControl = (ContentControl)uiElement;
            FindTextBoxex(uiElementAsContentControl.Content, foundOnes);
        }
        else if (uiElement is Decorator)
        {
            var uiElementAsBorder = (Decorator)uiElement;
            FindTextBoxex(uiElementAsBorder.Child, foundOnes);
        }
    }

Then you call that method with:

        var tb = new List<TextBox>();
        FindTextBoxex(this, tb);
        // now you got your textboxes in tb!


回答2:

You can also use the following generic method from the VisualTreeHelper documentation to get all your child controls of a given type:

internal static void FindChildren<T>(List<T> results, DependencyObject startNode)
  where T : DependencyObject
{
    int count = VisualTreeHelper.GetChildrenCount(startNode);
    for (int i = 0; i < count; i++)
    {
        DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
        if ((current.GetType()).Equals(typeof(T)) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
        {
            T asType = (T)current;
            results.Add(asType);
        }
        FindChildren<T>(results, current);
    }
}

It basically recursively get the children for the current item and add any item matching the requested type to the provided list.

Then, you just have to do the following somewhere to get your elements:

var allTextBoxes    = new List<TextBox>();
FindChildren(allTextBoxes, this);


回答3:

To my mind, you could do it in the same way as in WPF. Because UWP uses mostly the same XAML that WPF.

So, please check out answer for the same question about WPF