当前位置: 首页 > news >正文

WPF中查找控件的扩展类

在wpf中查找控件要用到VisualTreeHelper类,但这个类并没有按照名字查找控件的方法,于是搜索网络,整理出下面这个类,感觉用起来很是方便。

贴出来,供大家参考。

    /// <summary>
    /// WPF/Silverlight 查找控件扩展方法
    /// </summary>
    public static class VisualHelperTreeExtension
    {
        /// <summary>
        /// 根据控件名称,查找父控件
        /// elementName为空时,查找指定类型的父控件
        /// </summary>
        public static T GetParentByName<T>(this DependencyObject obj, string elementName)
        where T : FrameworkElement
        {
            DependencyObject parent = VisualTreeHelper.GetParent(obj);
            while (parent != null)
            {
                if ((parent is T) && (((T)parent).Name == elementName || string.IsNullOrEmpty(elementName)))
                {
                    return (T)parent;
                }
                parent = VisualTreeHelper.GetParent(parent);
            }

            return null;
        }

        /// <summary>
        /// 根据控件名称,查找子控件
        /// elementName为空时,查找指定类型的子控件
        /// </summary>
        public static T GetChildByName<T>(this DependencyObject obj, string elementName)
        where T : FrameworkElement
        {
            DependencyObject child = null;
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);
                if (child is T && (((T)child).Name == elementName) || (string.IsNullOrEmpty(elementName)))
                {
                    return (T)child;
                }
                else
                {
                    T grandChild = GetChildByName<T>(child, elementName);
                    if (grandChild != null)
                    {
                        return grandChild;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 根据控件名称,查找子控件集合
        /// elementName为空时,查找指定类型的所有子控件
        /// </summary>
        public static List<T> GetChildsByName<T>(this DependencyObject obj, string elementName)
        where T : FrameworkElement
        {
            DependencyObject child = null;
            List<T> childList = new List<T>();
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                child = VisualTreeHelper.GetChild(obj, i);
                if (child is T && (((T)child).Name == elementName) || (string.IsNullOrEmpty(elementName)))
                {
                    childList.Add((T)child);
                }
                else
                {
                    List<T> grandChildList = GetChildsByName<T>(child, elementName);
                    if (grandChildList != null)
                    {
                        childList.AddRange(grandChildList);
                    }
                }
            }
            return childList;
        }
    }

使用的时候非常简单,比如查找datagrid里模板列的一个叫“myTextBox”的文本框,可以这样写:

                var child = dataGrid.GetChildByName<TextBox>("myTextBox");
                if (child != null)
                {
                    child.Text = "abc";
                }

注意:初期化页面的时候,如果查找控件的代码放在Loaded事件中,会找不到控件;应该放在LayoutUpdated事件中,这时候xaml已经加载完毕,所有的子控件才能取到。

但是LayoutUpdated事件只要页面有更新,它都会触发,如果要达到Loaded事件的效果,我们可以设置一个flag在控制代码只在初期化时执行一次,现在也没有想到更好的办法来实现,大概如下:

        bool firstLoad = true;
        private void UserControl_LayoutUpdated(object sender, EventArgs e)
        {
            if (firstLoad)
            {
                //第一次加载要执行的代码
                //...
                firstLoad = false;
            }
        }

相关文章:

  • 获取IP和mac地址
  • OSPF ProcessID(进程号)详解
  • D3js技术文档 可视化展现
  • 推荐一本HTML5实例书,小白也看得会的《HTML5网页开发实例详解》
  • 使用apache bench(ab)压力测试
  • 编写高性能Web应用程序的10个技巧
  • java使用httpcomponents发送get请求
  • 比较大气的网页元素
  • oracle sql developer 无法启动的解决办法
  • RobotFrameWork(四)变量运算与Evaluate
  • vds与vcenter
  • wxPython Bind key events
  • 润乾报表实现预置分组报表及改进
  • mysql读写分离amoeba实现
  • ASP.NET MVC ViewBag/ViewData/TempData区别
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • FastReport在线报表设计器工作原理
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • js ES6 求数组的交集,并集,还有差集
  • oschina
  • windows-nginx-https-本地配置
  • 从零开始学习部署
  • 前端js -- this指向总结。
  • 前端性能优化--懒加载和预加载
  • 如何学习JavaEE,项目又该如何做?
  • 山寨一个 Promise
  • 通过几道题目学习二叉搜索树
  • 学习HTTP相关知识笔记
  • 用Canvas画一棵二叉树
  • No resource identifier found for attribute,RxJava之zip操作符
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​Java并发新构件之Exchanger
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • $forceUpdate()函数
  • (分布式缓存)Redis持久化
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • ***通过什么方式***网吧
  • .net core 控制台应用程序读取配置文件app.config
  • .Net Web项目创建比较不错的参考文章
  • .Net8 Blazor 尝鲜
  • .net与java建立WebService再互相调用
  • @TableId注解详细介绍 mybaits 实体类主键注解
  • [1]-基于图搜索的路径规划基础
  • [1525]字符统计2 (哈希)SDUT
  • [20171102]视图v$session中process字段含义
  • [28期] lamp兄弟连28期学员手册,请大家务必看一下
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [Android]创建TabBar
  • [CQOI 2010]扑克牌