摘要:用过VB6的人都会对控件数组念念不忘,因为控件数组在处理多个控件统一事件上确实很方便。.NET Framework没有引入控件数组这一概念,这是因为.NET Framework的类型系统很完善,可以实现控件数组原来的功能。只是这样凭空增加了一些麻烦,我们不是需要在Handls字句后面写一长串控件名称,就是要用写数遍AddHandler或C#的+=语句给多个控件绑定同一个事件。为了减轻没有控件数组日子的痛苦,我写了这个替代方案:共享事件容器。在编写它的过程中,我用了泛型,但其实不用泛型也可以做到,只是泛型能够约束容器内控件的类型,减少可能的运行时错误。
在看实现方法之前,先来看看共享事件容器是怎么操作的。首先你先要放一些相同类型控件到窗体上,这些就是你的控件数组元素了,假设是button1,button2和button3。然后在窗体的构造函数或Load事件中添加如下代码:
ba = New ShareEventsContainer(Of Button) '创建一个共享事件容器ba.AddRange(New Button() {Button1, Button2}) '用AddRange可以添加多个控件ba.Add(Button3) '当然Add方法也是支持的了
这就是共享事件容器了,就像是一般的集合一样,你可以用数组的语法操纵其中的对象。接下来就是重头戏了,我们要将容器内的全部控件的Click事件都绑定到同一个方法上,比如这个方法
Public Sub Buttons_Click(ByVal sender As Object, ByVal e As EventArgs) MsgBox("Hello! I'm " & CType(sender, Button).Name)End Sub
则接着在刚才初始化共享事件容器语句的后面写事件绑定代码:
ba.AddHandler("Click", New EventHandler(AddressOf Buttons_Click))
有点像VB的语法,其实我就是取了个神似。这里事件名称是要用字符串表示的,可别写错了。而事件处理程序的委托也与一般的事件绑定语句不一样,这时必须将委托类型写出来,还得写正确了。VB和C#2.0的委托类型推定在这时是不起作用的。你还可以写更多的AddHandler,绑定其他事件。
好了,就这么简单,事件已经绑定好了。更进一步的是,将来继续往这个容器内添加新的按钮,他们的事件也会自动绑定到这时预定的所有处理程序上,而从容器中移除控件,其事件会自动解除绑定。你还可以在任意地方用AddHandler和RemoveHandler方法添加和删除新的事件处理程序,支持多播事件方法。
如果你觉得这个方法值得用用,那就可以看下面的实现代码了:VB2005 BETA1
Imports System.Collections.GenericImports System.Reflection'包含委托的列表类型Imports DelegateList = System.Collections.Generic.List(Of System.MulticastDelegate)''' <summary>''' 提供一个共享事件容器,容器内的控件可以共享事件处理过程''' </summary>''' <typeparam name="T">控件的类型,不支持Menu</typeparam>''' <remarks>''' 共享事件容器在事件处理上类似于Visual Basic 6.0或更早版本的控件数组,''' 它可以将多个控件的事件绑定到同一个处理过程上,方便进行功能一致的操作。''' </remarks>Public Class ShareEventsContainer(Of T) Inherits Collection(Of T) '保存当前共享事件容器所预定的全部事件 '为了支持多播事件,必须采用这种结构的存储方式 Private events As Dictionary(Of String, DelegateList) Private controlType As Type ''' <summary> ''' 初始化一个默认的共享事件容器 ''' </summary> Public Sub New() MyBase.New() controlType = GetType(T) events = New Dictionary(Of String, DelegateList) End Sub ''' <summary> ''' 初始化一个共享事件容器,并添加初始的控件 ''' </summary> ''' <param name="controls"></param> Public Sub......[
阅读全文]