WinForm控件选择器
jQuery和Css的控件选择器用起来非常畅快,相信用过的人都会有这种感觉,而WinForm则是通过Name来实现窗体中控件的选择,在选择单个控件的时候是很方便,但是当选择具有一类特征的控件时,则显得有些乏力。于是我仿照jQuery和Css来实现了一个WInForm的控件选择器,而且是用扩展方法实现,这样只需要添加一个命名空间就可以方便的使用了。下面是实现的源码及一些简单的示例代码。
1 /// <summary> 2 /// WinForm控件选择器 3 /// </summary> 4 public static class Selector 5 { 6 //内部辅助函数,用于获取指定控件内所有子控件,采用yield return可以减少代码编写量 7 //由于该函数是延迟加载,如果在实际使用过程中直接返回IEnumerable<Control>可能会产生一些问题 8 //因此在选择器的公开函数中均返回数组 9 //另外从常理来说,由于在选择的子控件数量应为固定的,因此没有返回List,而且数组对系统资源的消耗要小于List 10 static IEnumerable<Control> AllNative(this Control ctrl) 11 { 12 foreach (Control c in ctrl.Controls) 13 { 14 yield return c; 15 foreach (Control sub in c.AllNative()) 16 { 17 yield return sub; 18 } 19 } 20 } 21 /// <summary> 22 /// 返回控件中所有子控件 23 /// </summary> 24 public static Control[] All(this Control ctrl) 25 { 26 return ctrl.AllNative().ToArray(); 27 } 28 /// <summary> 29 /// 返回控件中所有符合条件的子控件 30 /// </summary> 31 /// <param name="predicate">筛选条件</param> 32 public static Control[] All(this Control ctrl, Func<Control, bool> predicate) 33 { 34 return ctrl.AllNative().Where(predicate).ToArray(); 35 } 36 /// <summary> 37 /// 返回控件中所有指定类型的子控件 38 /// </summary> 39 /// <typeparam name="T">需要选择的子控件类型</typeparam> 40 public static T[] All<T>(this Control ctrl) 41 where T:Control 42 { 43 return ctrl.All().OfType<T>().ToArray(); 44 } 45 /// <summary> 46 /// 返回控件中所有指定类型且符合条件的子控件 47 /// </summary> 48 /// <typeparam name="T">需要选择的子控件类型</typeparam> 49 /// <param name="predicate">筛选条件</param> 50 public static T[] All<T>(this Control ctrl, Func<T, bool> predicate) 51 where T : Control 52 { 53 return ctrl.All().OfType<T>().Where(predicate).ToArray(); 54 } 55 }
在一个Form中添加若干控件,如下图所示
添加三个按钮事件做测试:
1 private void button1_Click(object sender, EventArgs e) 2 { 3 foreach (var b in this.All<Button>(b => b.FlatStyle == FlatStyle.Flat)) 4 { 5 b.BackColor = Color.Red; 6 } 7 8 } 9 10 private void button2_Click(object sender, EventArgs e) 11 { 12 foreach (var c in this.groupBox1.All()) 13 { 14 c.BackColor = Color.Blue; 15 } 16 17 } 18 19 private void button3_Click(object sender, EventArgs e) 20 { 21 foreach (var c in this.All()) 22 { 23 c.Text = "haha"; 24 } 25 }
下面一次是点击三个按钮之后的效果
从结果来看,代码是按照设计意图来运行的。