无法在VisualTreeHelper中看到用户控件内的控件

4

我在WPF 4.0中有一个UserControl,其中包含按钮、标签、文本框等控件......

我想循环遍历这些控件,当我找到一个按钮时,我想获取它的名称并将其保存到我的列表中。基本上,我想做的就是创建一个Names_list,其中包含用户控件中所有按钮的名称。

我有一个方法可以迭代所有控件,如果找到一个按钮,就会保存它的名称 -

  public void EnumVisual(Visual myVisual)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
        {
            // Retrieve child visual at specified index value.
            Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i);

            Button _button = childVisual as Button;
            if (_button != null)
            {
                Class_Button _newButtonClass = new Class_Button();
                if (_button.Name != null)
                {
                    _newButtonClass.ButtonName = _button.Name; 
                }
                ButtonsList.Add(_newButtonClass);
            }

            // Enumerate children of the child visual object.
            EnumVisual(childVisual);

        }
    }

我总是得到一个空列表。 当我通过调试进入代码并查看我的UserControl的VisualTree时,我可以看到所有的面板、GroupBoxes和网格,但我看不到按钮、标签和文本框,尽管每个控件都有一个x:Name,每个控件都是x:FieldModifier="public"。这非常奇怪...我也无法理解原因以及如何解决这个问题... 有人能告诉我我做错了什么吗? 谢谢


1
你什么时候调用EnumVisual()函数?你确定模板在那个时候已经被应用了吗? - GazTheDestroyer
@GazTheDestroyer 我创建了我的MainWindow,其中包含UserControl,然后在它显示后,我调用函数通过单击menuItem获取按钮列表.....到那时,我可以看到UserControl在我的MainWindow中.... - N.D
这并不意味着UserControl已经加载完毕。在您的代码进入该方法时,它可能正在进行中间过程。尝试在某个临时按钮单击事件处理程序中调用该方法。 - EvAlex
@EvAlex 你说得对....用户控件放置在一个选项卡项目上,只有当我打开选项卡并实际看到用户控件时,它的按钮才出现在按钮列表中....我不明白为什么面板会生成而内部的控件却没有.....谢谢你的帮助 :) - N.D
元素以自下而上的方式进行初始化,因此按钮应该在它们的容器之前进行初始化。并且在渲染之前。您如何将这些按钮添加到UserControl中?我猜不是在XAML中吧? - EvAlex
2个回答

1

您可以使用像SnoopWPF Inspector这样的工具来检查您控件的可视树。如果这些工具能够做到这一点,那么错误肯定在您的代码中某个地方,对吧?


1

根据 @GazTheDestroyer 的建议,在尝试使用 VisualTreeHelper 之前,确保已应用控件模板。请尝试:

public void EnumVisual(Visual myVisual)
{
    if(myVisual is FrameworkElement)
        ((FrameworkElement)myVisual).ApplyTemplate();

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
    {
        // Retrieve child visual at specified index value.
        Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i);

        Button _button = childVisual as Button;
        if (_button != null)
        {
            Class_Button _newButtonClass = new Class_Button();
            if (_button.Name != null)
            {
                _newButtonClass.ButtonName = _button.Name; 
            }
            ButtonsList.Add(_newButtonClass);
        }

        // Enumerate children of the child visual object.
        EnumVisual(childVisual);

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接