[WPF]查找子元素、查找父元素方法

13 篇文章 0 订阅

一、查找子元素的方法:


        #region Functions.Visual.Child

        /// <summary>
        /// 枚举:搜索子元素模式
        /// </summary>
        public enum FindChildrenMode
        {
            /// <summary> 只限于根层元素 </summary>
            ROOT = 0,
            /// <summary> 按分支顺序 </summary>
            BRANCH = 1,
            /// <summary> 按层的顺序 </summary>
            LAYER = 2,
        }

        #endregion

        #region Functions.Visual.Child

        /// <summary>
        /// Get:获取符合类型的迭代
        /// </summary>
        /// <typeparam name="T">查找的类型</typeparam>
        /// <param name="visual">查找的元素</param>
        /// <param name="mode">搜索子元素模式</param>
        /// <param name="isSearchT">搜索对象是否包括T元素</param>
        /// <returns></returns>
        public static IEnumerable<T> GetChildrenEnumerable<T>(DependencyObject visual, FindChildrenMode mode, bool isSearchT = true)
            where T : FrameworkElement
        {
            if (visual == null) { yield break; }

            var _count = VisualTreeHelper.GetChildrenCount(visual);

            switch (mode)
            {
                case FindChildrenMode.ROOT:
                    {
                        #region ROOT

                        for (int i = 0; i < _count; i++)
                        {
                            var _child = VisualTreeHelper.GetChild(visual, i);

                            if (_child == null) { continue; }

                            if (_child is T _target)
                            {
                                yield return _target;
                            }

                        }

                        #endregion
                    }
                    break;
                case FindChildrenMode.BRANCH:
                    {
                        #region BRANCH

                        for (int i = 0; i < _count; i++)
                        {
                            var _child = VisualTreeHelper.GetChild(visual, i);

                            if (_child == null) { continue; }

                            if (_child is T _target)
                            {
                                yield return _target;
                                if (!isSearchT) { continue; }
                            }

                            var _enumerable = GetChildrenEnumerable<T>(_child, mode, isSearchT);
                            foreach (T _sub in _enumerable)
                            {
                                yield return _sub;
                            }
                        }

                        #endregion
                    }
                    break;
                case FindChildrenMode.LAYER:
                    {
                        #region BRANCH

                        for (int i = 0; i < _count; i++)
                        {
                            var _child = VisualTreeHelper.GetChild(visual, i);

                            if (_child == null) { continue; }

                            if (_child is T _target)
                            {
                                yield return _target;
                            }
                        }

                        for (int i = 0; i < _count; i++)
                        {
                            var _child = VisualTreeHelper.GetChild(visual, i);

                            if (_child == null) { continue; }
                            if (!isSearchT)
                            {
                                if (_child is T) { continue; }
                            }

                            var _enumerable = GetChildrenEnumerable<T>(_child, mode, isSearchT);
                            foreach (T _sub in _enumerable)
                            {
                                yield return _sub;
                            }
                        }

                        #endregion
                    }
                    break;
            }
        }

        /// <summary>
        /// Get:获取符合类型的迭代
        /// </summary>
        /// <typeparam name="T">查找的类型</typeparam>
        /// <param name="visual">查找的元素</param>
        /// <returns></returns>
        public static IEnumerable<T> GetChildrenEnumerable<T>(DependencyObject visual)
            where T : FrameworkElement
        {
            return GetChildrenEnumerable<T>(visual, FindChildrenMode.LAYER, true);
        }

        /// <summary>
        /// Get:获取所有符合类型的子元素
        /// </summary>
        /// <typeparam name="T">查找的类型</typeparam>
        /// <param name="visual">查找的元素</param>
        /// <returns></returns>
        public static List<T> FindAllChild<T>(DependencyObject visual)
            where T : FrameworkElement
        {
            var _list = new List<T>();
            if (visual == null) { return _list; }

            var _enumerable = GetChildrenEnumerable<T>(visual);
            _list.AddRange(_enumerable);

            return _list;
        }

        /// <summary>
        /// Get:获取首个符合类型的子元素
        /// </summary>
        /// <typeparam name="T">查找的类型</typeparam>
        /// <param name="visual">查找的元素</param>
        /// <returns></returns>
        public static T FirstChild<T>(DependencyObject visual)
            where T : FrameworkElement
        {
            if (visual == null) { return default; }

            var _enumerable = GetChildrenEnumerable<T>(visual);

            foreach (var _child in _enumerable)
            {
                if (_child == null) { continue; }
                return _child;
            }

            return default;
        }

        /// <summary>
        /// Get:获取首个符合类型的子元素
        /// </summary>
        /// <typeparam name="T">查找的类型</typeparam>
        /// <param name="visual">查找的元素</param>
        /// <param name="name">元素名称</param>
        /// <returns></returns>
        public static T FirstChild<T>(DependencyObject visual, string name)
            where T : FrameworkElement
        {
            if (visual == null) { return default; }

            var _enumerable = GetChildrenEnumerable<T>(visual);

            foreach (var _child in _enumerable)
            {
                if (_child == null) { continue; }
                if (_child.Name == name) { return _child; }
            }

            return default;
        }

        #endregion

二、查找父元素的方法:


        #region Functions.Visual.Parent

        /// <summary>
        /// Get:获取符合类型的父元素
        /// </summary>
        /// <typeparam name="T">父控件的类型</typeparam>
        /// <param name="visual">要找的是obj的父控件</param>
        /// <returns>目标父控件</returns>
        public static T GetParent<T>(DependencyObject visual)
            where T : FrameworkElement
        {
            if (visual == null) { return default; }

            var _parent = VisualTreeHelper.GetParent(visual);
            while (_parent != null)
            {
                if (_parent is T _pVisual) { return _pVisual; }

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

            return default;
        }

        /// <summary>
        /// Get:获取符合类型的父元素
        /// </summary>
        /// <typeparam name="T">父控件的类型</typeparam>
        /// <param name="visual">要找的是obj的父控件</param>
        /// <param name="name">想找的父控件的Name属性</param>
        /// <returns>目标父控件</returns>
        public static T GetParent<T>(Visual visual, string name)
            where T : FrameworkElement
        {
            if (visual == null) { return default; }

            var _parent = VisualTreeHelper.GetParent(visual);
            while (_parent != null)
            {
                if (_parent is T _pVisual)
                {
                    if (_pVisual.Name == name)
                    {
                        return _pVisual;
                    }
                }

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

            return default;

        }


        #endregion

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值