c# 扩展方法奇思妙用高级篇六:WinForm 控件选择器

本文介绍了一种在WinForm中使用的控件选择器实现方案,通过递归遍历控件树并应用过滤条件,实现了对特定类型的控件进行操作。示例展示了如何禁用所有按钮、反转指定组内复选框的状态以及改变标签颜色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

ScrollableControl 

图1  ScrollableControl类图

ButtonBase图2  ButtonBase类图

TextBoxBase

图3  TextBoxBase类图

ListControl

图4  ListControl类图

Label

图5  Label类图

Other

图6  其它常用

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

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

Form1 

图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#扩展方法奇思妙用》,敬请关注!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值