在可视化树中查找控件

4
我正在尝试从DataTemplate中获取我的SelectedRadioButton。
Wpf Inspector显示了可视树:

enter image description here

而在代码中:
    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是一个ContentPresenter,可以看到Wpf检查器中的图片,我相信从那里我必须能够找到SelectedRadioButton。变量control始终为null。
我在这里缺少什么?我使用这些 visualtreehelpers


1
在WPF中像这样操纵UI元素是非常罕见的。你想做什么? - Federico Berasategui
@HighCore 我想在初始化时设置自定义控件的属性。但是它们是通过ItemsControl中的DataTemplate生成的,我找不到任何访问点。 - Gerard
@Gerard 看起来应该通过数据绑定来完成。 - Federico Berasategui
@Gerard ;) 你试过了吗? - dev hedgehog
2
好的,那是一个不错的教程。我之前不知道这个。Dr wpf 调用 ApplyTemplate(); 来加载和初始化内部控件。我赞同这个教程。哈哈 - dev hedgehog
显示剩余2条评论
1个回答

7

我用来遍历可视树的代码没有使用ApplyTemplate()方法,因此无法找到树中的子元素。在我的情况下,以下代码可以解决问题:

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

感谢“dev hedgehog”指出的评论(我错过了这一点)。 我不会在生产代码中使用这种方法,必须使用类似于“HighCore”评论的数据绑定方式来完成。

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