Find control in the visual tree

[亡魂溺海] 提交于 2019-12-29 00:39:25

问题


I am trying to get my SelectedRadioButton from a DataTemplate.

Wpf Inspector showed the Visual Tree:

and in code:

    void menu_StatusGeneratorChanged(object sender, EventArgs e)
            {
                var status = Menu.Items.ItemContainerGenerator.Status;
                if (status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
                {
                    var item = Menu.Items.ItemContainerGenerator.ContainerFromIndex(0);
                    // item is a ContentPresenter
                    var control = Tools.FindChild<SelectedRadioButton>(item);
                    control = Tools.FindAncestor<SelectedRadioButton>(item);
                }
            }

item is a ContentPresenter, see the image of Wpf inspector, I believe from there I must be able to get to the SelectedRadioButton. The variable control is always null.
What am I missing here? I use these visualtreehelpers.


回答1:


The code that I used to traverse the Visual Tree did not use the ApplyTemplate() method for a FrameworkElement in the tree and therefore cildren could not be found. In my situation the following code works:

    /// <summary>
    /// Looks for a child control within a parent by name
    /// </summary>
    public static DependencyObject FindChild(DependencyObject parent, string name)
    {
        // confirm parent and name are valid.
        if (parent == null || string.IsNullOrEmpty(name)) return null;

        if (parent is FrameworkElement && (parent as FrameworkElement).Name == name) return parent;

        DependencyObject result = null;

        if (parent is FrameworkElement) (parent as FrameworkElement).ApplyTemplate();

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            result = FindChild(child, name);
            if (result != null) break;
        }

        return result;
    }

    /// <summary>
    /// Looks for a child control within a parent by type
    /// </summary>
    public static T FindChild<T>(DependencyObject parent)
        where T : DependencyObject
    {
        // confirm parent is valid.
        if (parent == null) return null;
        if (parent is T) return parent as T;

        DependencyObject foundChild = null;

        if (parent is FrameworkElement) (parent as FrameworkElement).ApplyTemplate();

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            foundChild = FindChild<T>(child);
            if (foundChild != null) break;
        }

        return foundChild as T;
    }

Thanks for the comments of "dev hedgehog" for pointing that out (I missed it).
I will not use this approach in production code, it has to be done with databinding like "HighCore" commented.



来源:https://stackoverflow.com/questions/19523139/find-control-in-the-visual-tree

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!