在Web开发中,jQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象。但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器。好在我们有扩展方法,可以很方便的打造一个。

我们先看几个类图,深入认识一下我们常用的WinForm控件:

图1  ScrollableControl类图

图2  ButtonBase类图

图3  TextBoxBase类图

图4  ListControl类图

图5  Label类图

图6  其它常用

从图1中可以看出,Form与Button、Label一样,也是一个Control。

WinForm中的一些控件(如Form、GroupBox、Panel)可以包含其它控件,我们可以通过Control类的Controls属性进行遍历。控件是可以层层包含的,如下图:

图7  示例窗体

Form1是顶级控件,它包含了四个子控件:groupBox1、groupBox2、button1、button2。groupBox1和groupBox2中也包含了多个控件。层层包含最终形成了一个树型结构。

我们打造的WinForm的控件选择器,实质上就是一个树的遍历器。下是就是该选择器的参考实现代码:


 1     public static IEnumerable<T> GetControls<T>(this Control control, Func<T, bool> filter) where T : Control

 2     {

 3         foreach (Control c in control.Controls)

 4         {

 5             if (c is T)

 6             {

 7                 T t = c as T;

 8                 if (filter != null)

 9                 {

10                     if (filter(t))

11                     {

12                         yield return t;

13                     }

14                     else

15                     {

16                         foreach (T _t in GetControls<T>(c, filter))

17                             yield return _t;

18                     }

19                 }

20                 else

21                     yield return t;

22             }

23             else

24             {

25                 foreach (T _t in GetControls<T>(c, filter))

26                     yield return _t;

27             }

28         }

29     }

(代码中存在一处bug,请参见斯克迪亚的回复#4楼)

有了GetControls选择器,我们就可以在WinForm中进行一些“复杂”应用,示例如下(以图7为例):


 1     // 构造函数

 2     public Form1()

 3     {

 4         InitializeComponent();

 5         //禁用所有Button

 6         this.GetControls<Button>(null).ForEach(b => b.Enabled = false);

 7         //反选groupBox1中CheckBox

 8         this.GetControls<CheckBox>(c => c.Parent == groupBox1)

 9             .ForEach(c => c.Checked = !c.Checked);

10         //将label1的前景色设为红色

11         this.GetControls<Label>(l => l.Name == "label1").FirstOrDefault().ForeColor

12             = Color.Red;

13     }

附上常用的ForEach扩展:

1     public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)

2     {

3         foreach (var item in source) 

4             action(item);

5     }

感觉如何?欢迎批评指正!(代码仅供参考)

C# 扩展方法奇思妙用高级篇六:WinForm 控件选择器的更多相关文章

  1. c# 扩展方法 奇思妙用 高级篇 九:OrderBy(string propertyName, bool desc)

    下面是 Queryable 类 中最常用的两个排序的扩展方法: 1 2 public static IOrderedQueryable<TSource> OrderBy<TSourc ...

  2. c# 扩展方法奇思妙用基础篇八:Distinct 扩展(转载)

    转载地址:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html 刚看了篇文章 <Linq的Distin ...

  3. c# 扩展方法奇思妙用基础篇八:Distinct 扩展

    刚看了篇文章 <Linq的Distinct太不给力了>,文中给出了一个解决办法,略显复杂. 试想如果能写成下面的样子,是不是更简单优雅 var p1 = products.Distinct ...

  4. c# 扩展方法奇思妙用基础篇五:Dictionary<TKey, TValue> 扩展

    Dictionary<TKey, TValue>类是常用的一个基础类,但用起来有时确不是很方便.本文逐一讨论,并使用扩展方法解决. 向字典中添加键和值 添加键和值使用 Add 方法,但很多 ...

  5. c# 扩展方法奇思妙用基础篇九:Expression 扩展

    http://www.cnblogs.com/ldp615/archive/2011/09/15/expression-extension-methods.html .net 中创建 Expressi ...

  6. c# 扩展方法奇思妙用

    # 扩展方法出来已久,介绍扩展方法的文章也很多,但都是笼统的.本人最近一直在思考扩展方法的应用,也悟出了一些,准备将这最近一段时间对扩展方法的思考,写成一个系列文章.每个文章只介绍一个应用方面,篇幅不 ...

  7. c# 扩展方法奇思妙用集锦

    本文转载:http://www.cnblogs.com/ldp615/archive/2009/08/07/1541404.html 其中本人觉得很经典的:c# 扩展方法奇思妙用基础篇五:Dictio ...

  8. [转]在WPF中使用WinForm控件方法

    本文转自:http://blog.csdn.net/lianchangshuai/article/details/6415241 下面以在Wpf中添加ZedGraph(用于创建任意数据的二维线型.条型 ...

  9. 多线程访问winform控件出现异常的解决方法

    一.  多线程访问winform控件出现异常的解决方法 1.  问题描述<1> 如果创建某控件的线程之外的其他线程试图调用该控件,则会引发一个 InvalidOperationExcept ...

随机推荐

  1. [Swift系列]002-基础语法

    基础语法就那老几样,很快可以说完 [常量.变量] 1.变量用 var,系统自动去判断类型,但变量再次赋值需保持数据类型一致 var  a=50 相信用过js/java/C#的,对这个var都不陌生 使 ...

  2. 【C#学习笔记】保存文件

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. 支持向量机之Hinge Loss 解释

    Hinge Loss 解释 SVM 求解使通过建立二次规划原始问题,引入拉格朗日乘子法,然后转换成对偶的形式去求解,这是一种理论非常充实的解法.这里换一种角度来思考,在机器学习领域,一般的做法是经验风 ...

  4. Cadence Allegro导网表的错误问题解决

    在Allegro导入网表的时候,有时候会出现这样一个错误问题,如下: ------ Oversights/Warnings/Errors ------ #1   ERROR(SPMHNI-235): ...

  5. JBPM4之decision节点:1、好学生 | 坏学生

    JBPM入门系列文章: JBPM4入门——1.jbpm简要介绍 JBPM4入门——2.在eclipse中安装绘制jbpm流程图的插件 JBPM4入门——3.JBPM4开发环境的搭建 JBPM4入门—— ...

  6. 502 Bad Gateway nginx 解决

    打开 /usr/local/php/etc/php-fpm.conf 调大以下两个参数(根据服务器实际情况,过大也不行) <value name=”max_children”>5120&l ...

  7. Android开发如何在4.0及以上系统中自定义TitleBar

    本文将通过一个实例讲解怎么实现在4.0及以上系统版本中实现自定义TitleBar,这只是我自己找到的一种方法; xml布局文件 activity_main.xml <RelativeLayout ...

  8. Android 校验apk文件渠道号、包名、版本号

    功能:可查看单个或目录下所有apk文件的渠道号.包名.版本号 下载地址:http://download.csdn.net/detail/zgz345/9248487使用:以查看包名.版本号为例 1.c ...

  9. PHP 优化详解

    笔者收集的这些技巧来源较广,完整性不能保证. 由于数量较多,这些优化技巧没有经过测试.请各位看官在使用之前自行测试,毕竟这些技巧是否能派上用场,还是需要由PHP所在的独特环境所决定的. 目录索引 找到 ...

  10. grails下的httpclient

    httpclient已经发布到4.3版本了,其中的API发生了巨大的变化,尤其是对于关闭连接显得更加容易理解,比如引入了CloseableHttpResponse. 然而grails2.3.2中自带了 ...