您的位置:首页 > 编程语言 > C#

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

2009-11-08 21:17 447 查看
在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#扩展方法奇思妙用》,敬请关注!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: