【WPF】查找父/子控件(元素、节点)

整理一下项目中常用的找控件功能,包括找父/子控件、找到所有同类型子控件(比如ListBox找到所有Item)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace MyDemo.Utils
{
    /// 
    /// 用于查找控件的工具类:找到父控件、子控件
    /// 
    class ControlsSearchHelper
    {
        /// 
        /// 查找父控件
        /// 
        /// 父控件的类型
        /// 要找的是obj的父控件
        /// 想找的父控件的Name属性
        /// 目标父控件
        public static T GetParentObject(DependencyObject obj, string name) where T : FrameworkElement
        {
            DependencyObject parent = VisualTreeHelper.GetParent(obj);

            while (parent != null)
            {
                if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name)))
                {
                    return (T)parent;
                }

                // 在上一级父控件中没有找到指定名字的控件,就再往上一级找
                parent = VisualTreeHelper.GetParent(parent);
            }

            return null;
        }


        /// 
        /// 查找子控件
        /// 
        /// 子控件的类型
        /// 要找的是obj的子控件
        /// 想找的子控件的Name属性
        /// 目标子控件
        public static T GetChildObject(DependencyObject obj, string name) where T : FrameworkElement
        {
            DependencyObject child = null;
            T grandChild = null;

            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);

                if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
                {
                    return (T)child;
                }
                else
                {
                    // 在下一级中没有找到指定名字的子控件,就再往下一级找
                    grandChild = GetChildObject(child, name);
                    if (grandChild != null)
                        return grandChild;
                }
            }

            return null;

        }


        /// 
        /// 获取所有同一类型的子控件
        /// 
        /// 子控件的类型
        /// 要找的是obj的子控件集合
        /// 想找的子控件的Name属性
        /// 子控件集合
        public static List GetChildObjects(DependencyObject obj, string name) where T : FrameworkElement
        {
            DependencyObject child = null;
            List childList = new List();

            for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);

                if (child is T && (((T)child).Name == name || string.IsNullOrEmpty(name)))
                {
                    childList.Add((T)child);
                }

                childList.AddRange(GetChildObjects(child, ""));
            }

            return childList;

        }
    }
}

        public static IEnumerable FindVisualChildren(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);

                    if (child != null && child is T)
                        yield return (T)child;

                    foreach (T childOfChild in FindVisualChildren(child))
                        yield return childOfChild;
                }
            }
        }

小结:

  • 采用了递归的方式,在多级中去查找指定Name属性的父控件/子控件。如果不想指定名字,或者只想在上/下一级中查找(不递归),根据需求再稍作修改。
  • 虽说这是用的WPF的查找方式,依赖的库很多无法跨平台,但是这种递归查找的方式值得学习和借鉴。(例如以后做Unity项目时可以拿来参考)

重要的学习参考:

http://www.wxzzz.com/1408.html
http://www.cnblogs.com/_ymw/archive/2013/02/18/2915870.html

 

你可能感兴趣的:(【WPF】查找父/子控件(元素、节点))