如何在可视化树中查找元素?wp7

3

为什么在app.xaml中有一个Grid - AnthonyWJones
我有一个音频面板,它在所有页面中显示。 - SevenDays
3个回答

2
更新:您需要结合我的答案和H.B.的答案。请使用下面的FindChild版本,并将调用FindChild的方式更改为:
var grid = FindChild<Grid>(Application.Current.RootVisual, "audioPanel");

由于您正在为手机应用程序框架设置样式,因此H.B.的评论中“应用该控件”的控件很可能是RootVisual(可能会有例外情况,我不确定)。
此外,我假设您在pastebin中的App.xaml的“...”部分中有一个ContentPresenter,否则我认为您的样式将无法工作。
如果您正在使用您链接到的问题中的已接受答案(WPF查找控件的方法),并且您的“audioPanel”网格嵌套在另一个网格中,则仍然找不到它-该代码存在错误。以下是一个更新后的版本,即使控件被嵌套,也将起作用:
    public static T FindChild<T>(DependencyObject parent, string childName)
        where T : DependencyObject
    {
        // Confirm parent and childName are valid. 
        if (parent == null)
        {
            return null;
        }

        T foundChild = null;

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(parent, i);
            // If the child is not of the request child type child
            var childType = child as T;
            if (childType == null)
            {
                // recursively drill down the tree
                foundChild = FindChild<T>(child, childName);

                // If the child is found, break so we do not overwrite the found child. 
                if (foundChild != null)
                {
                    break;
                }
            }
            else if (!string.IsNullOrEmpty(childName))
            {
                var frameworkElement = child as FrameworkElement;
                // If the child's name is set for search
                if (frameworkElement != null && frameworkElement.Name == childName)
                {
                    // if the child's name is of the request name
                    foundChild = (T) child;
                    break;
                }

                // Need this in case the element we want is nested
                // in another element of the same type
                foundChild = FindChild<T>(child, childName);
            }
            else
            {
                // child element found.
                foundChild = (T) child;
                break;
            }
        }

        return foundChild;
    }
}

NullReferenceException,网格为空。我该如何解决这个问题? - SevenDays

1
如果它在 App.xaml 中,我会认为它是 Application.Resources 中资源的一部分,因为未被任何地方使用的资源不会在可视树中,这行不通。
如果是这样,您可以尝试从资源中获取对象的根,并从那里搜索,例如:
var root = Application.Current.Resources["MyKey"] as FrameworkElement;
Grid found = this.FindChild<Grid>(root, "audioPanel");

什么是"MyKey"?如果我改成"mainFrameStyle",就会出现NullReferenceException。 - SevenDays
好的,既然这是一个样式,你不需要获取样式本身,而是应该获得应用在其上的控件。("MyKey" 应为 "mainFrameStyle" - H.B.
我说过“本来应该是”,并将其放在括号中,请重新阅读我的最后一条评论... - H.B.

0

仅为完整起见,E. Z. Hart的版本存在一个错误,即发现的子项被覆盖。这是一个可行的版本。

public static T FindChild<T>(this DependencyObject parent, string childName = null) where T : DependencyObject
    {
        // Confirm parent and childName are valid. 
        if (parent == null)
            return null;

        T foundChild = null;

        var childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (var i = 0; foundChild == null && i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);                

            // If the child is not of the request child type child
            var childType = child as T;
            if (childType == null)
            {                   
                // recursively drill down the tree
                foundChild = FindChild<T>(child, childName);                    
            }
            else if (!string.IsNullOrEmpty(childName))
            {
                var frameworkElement = child as FrameworkElement;
                // If the child's name is set for search
                if (frameworkElement != null && frameworkElement.Name == childName)
                {
                    // if the child's name is of the request name
                    foundChild = (T)child;                        
                }
                else
                {
                    // Need this in case the element we want is nested
                    // in another element of the same type
                    foundChild = FindChild<T>(child, childName);
                }                    
            }
            else
            {
                // child element found.
                foundChild = (T)child;                    
            }
        }

        return foundChild;
    }

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