zoukankan      html  css  js  c++  java
  • 【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
    {
        /// <summary>
        /// 用于查找控件的工具类:找到父控件、子控件
        /// </summary>
        class ControlsSearchHelper
        {
            /// <summary>
            /// 查找父控件
            /// </summary>
            /// <typeparam name="T">父控件的类型</typeparam>
            /// <param name="obj">要找的是obj的父控件</param>
            /// <param name="name">想找的父控件的Name属性</param>
            /// <returns>目标父控件</returns>
            public static T GetParentObject<T>(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;
            }
    
    
            /// <summary>
            /// 查找子控件
            /// </summary>
            /// <typeparam name="T">子控件的类型</typeparam>
            /// <param name="obj">要找的是obj的子控件</param>
            /// <param name="name">想找的子控件的Name属性</param>
            /// <returns>目标子控件</returns>
            public static T GetChildObject<T>(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<T>(child, name);
                        if (grandChild != null)
                            return grandChild;
                    }
                }
    
                return null;
    
            }
    
    
            /// <summary>
            /// 获取所有同一类型的子控件
            /// </summary>
            /// <typeparam name="T">子控件的类型</typeparam>
            /// <param name="obj">要找的是obj的子控件集合</param>
            /// <param name="name">想找的子控件的Name属性</param>
            /// <returns>子控件集合</returns>
            public static List<T> GetChildObjects<T>(DependencyObject obj, string name) where T : FrameworkElement
            {
                DependencyObject child = null;
                List<T> childList = new List<T>();
    
                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<T>(child, ""));
                }
    
                return childList;
    
            }
        }
    }
    
            public static IEnumerable<T> FindVisualChildren<T>(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<T>(child))
                            yield return childOfChild;
                    }
                }
            }
    

    小结:

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

    重要的学习参考:

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

  • 相关阅读:
    Codeforces 877 C. Slava and tanks
    Codeforces 877 D. Olya and Energy Drinks
    2017 10.25 NOIP模拟赛
    2017 国庆湖南 Day1
    UVA 12113 Overlapping Squares
    学大伟业 国庆Day2
    51nod 1629 B君的圆锥
    51nod 1381 硬币游戏
    [JSOI2010]满汉全席
    学大伟业 2017 国庆 Day1
  • 原文地址:https://www.cnblogs.com/guxin/p/wpf-how-to-get-parent-or-child-node-object.html
Copyright © 2011-2022 走看看