• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

在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扩展:

    public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
    {
        foreach (var item in source) 
            action(item);
    }

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


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap