在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. BZOJ 1821 部落划分

    kruskal.第k-1大的边. 其实prim会更快. #include<iostream> #include<cstdio> #include<cstring> ...

  2. php字符串与正则表达式试题 Zend权威认证试题讲解

    字符串是PHP的“瑞士军刀”——作为一种Web开发语言,PHP最常打交道的就是字符串.因此对于开发者来说,处理字符串是一项非常基础的技能.幸运的是,由于PHP开发团队的努力,PHP对字符串的处理相当易 ...

  3. 【转】让Souce Insight支持多种语言的语法高亮:Python,Ruby,ARM汇编,windows脚本文件(bat/batch),PPC,SQL,TCL,Delphi等

    原文网址:http://www.crifan.com/source_insight_support_highlight_for_python_ruby_arm_batch_ppc_sql_tcl_de ...

  4. SQL server2012连接不上

    数据库连接不上 其中一种可能的解决办法: 开始-所有程序-Microsoft SQL server 2012-配置工具-SQL Server 配置管理器-SQL server 服务-SQL serve ...

  5. MBTiles地图瓦片管理工具

    采用C#+GMap.NET+MBTiles数据库来实现. 具有以下功能: 1)  支持单个文件追加到mbtiles数据库. 2)  支持批量导入Google切片组织的地图瓦片. 3)  支持直接对MB ...

  6. CSS使jsp图片旋转90度

    <style > img{ margin:100px auto 0; -moz-transform:rotate(-90deg); -webkit-transform:rotate(-90 ...

  7. C#实现CAD数据转shape或mdb

    jojojojo2002 原文C#实现CAD数据转shape或mdb 本文所指的CAD数据为不带空间参考和扩展数据的数据.如果CAD带了空间参考或是扩展属性数据的话,就要采用图形和属性分离的方法转CA ...

  8. Microsoft Office 2010 requires 的 MSXML 版本 6.10.1129.0 be 已安装在您计算机的安装"的基于 Windows 7 的计算机上安装 Office 2010 时出现错误消息

    https://support.microsoft.com/zh-cn/kb/2290714

  9. [转]LoadRunner参数化详解

    http://www.cnblogs.com/fnng/archive/2012/06/22/2558900.html 距离上次使用loadrunner 已经有一年多的时间了.初做测试时在项目中用过, ...

  10. windows下ncl生成tiff图(案例)

    一:安装软件和准备数据 1.需要安装Vapor(注意安装路径不要存在空格) 注:版本2.4.2及以后 2.安装NCL,方法见http://www.cnblogs.com/striver-zhu/p/4 ...