处理多个对象的事件?如果不是控件的话,你可以试试用集合类来处理。举个简单的例子。 在类模块IEventHandler(事件接口)中Option ExplicitPublic Sub FireEvent()
End Sub在类模块MyObjects(集合类)中Option ExplicitImplements IEventHandlerPublic Event ObjectEvent()Private m_Col As New CollectionPublic Sub Add(objItem As ObjectItem, Optional ByVal Key As String)
objItem.EventHandler = Me
If Len(Key) Then m_Col.Add objItem, Key Else m_Col.Add objItem End If
End SubPrivate Sub IEventHandler_FireEvent() RaiseEvent ObjectEvent End Sub'其他的代码略...在类模块ObjectItem(要处理的对象)Option ExplicitPrivate m_EventHandler As IEventHandlerFriend Property Let EventHandler(ByVal Value As IEventHandler) Set m_EventHandler = Value End Property'Test方法通知实现这个接口的对象 Public Sub Test() m_EventHandler.FireEvent End Sub使用时Option ExplicitPrivate WithEvents mObjects As MyObjectsPrivate Sub Command1_Click()
Dim o As ObjectItem
If mObjects Is Nothing Then Set mObjects = New MyObjects
Set o = New ObjectItem
mObjects.Add o
o.TestEnd SubPrivate Sub mObjects_ObjectEvent() MsgBox "OK" End Sub
Private WithEvents Objects(UBound) As Class不支持定义数组的。
这是一个简单的例子: 新建一个普通工程,添加一个窗体,3个类模块:类模块IEvents: Option Explicit'interface IEventsPublic Sub Event1() End SubPublic Sub Event2(ByVal Param As Integer) End Sub类模块IYourObject: Option Explicit 'interface IYourObjectPublic Property Get YourProp() As String End PropertyPublic Sub YourSub(ByVal i As Integer) End SubPublic Sub SetEventHandler(EH As IEvents) End Sub类模块CYourObject: 'CYourObject - implements the IYourObject interface Option Explicit Implements IYourObject Dim m_Events As IEvents Private mYourProp As StringPublic Property Get YourProp() As String YourProp = IYourObject.YourProp End Property Public Sub YourSub(ByVal i As Integer) IYourObject_YourSub i End SubPublic Sub SetEventHandler(EH As IEvents) IYourObject.SetEventHandler EH End SubPrivate Sub Class_Initialize() mYourProp = "this is test" End SubPrivate Sub IYourObject_SetEventHandler(EH As IEvents) Set m_Events = EH End SubPrivate Property Get IYourObject_YourProp() As String 'raise an event IYourObject_YourProp = mYourProp m_Events.Event1 End PropertyPrivate Sub IYourObject_YourSub(ByVal i As Integer) ' raise an event m_Events.Event2 i End Sub窗体: Option Explicit Implements IEventsDim MyClassObj As IYourObjectPrivate Sub Command1_Click() MsgBox MyClassObj.YourProp End Sub' IEvents implementation Public Sub IEvents_Event1() MsgBox "Raised Event1 !!" End SubPublic Sub IEvents_Event2(ByVal Param As Integer) MsgBox "Raised Event2 !!" End Sub' form code Private Sub Form_Load() ' create the object Set MyClassObj = New CYourObject MyClassObj.SetEventHandler Me End Sub
看看我的做法,用一个通用数组类来管理索引及访问类 只是,事件没有办法传回.那位达人帮我想想办法Option Explicit 'in Form Private WithEvents CExample As Class_Example Private CArray As New Class_ObjectArrayPrivate Sub Form_Load() Dim i As Long For i = 1 To 3 Set CExample = New Class_Example CArray.CNew CExample Next i End SubPrivate Sub Form_Unload(Cancel As Integer) Set CExample = Nothing End SubPrivate Sub Form_DblClick() CArray.CItem(2).Raise End SubPrivate Sub CExample_CEvent(ByVal index As Long) Debug.Print index End Sub Option Explicit'Class_Example.cls Public index As LongPublic Event CEvent(ByVal index As Long)Public Function Raise() RaiseEvent CEvent(index) End FunctionOption Explicit 'Class_ObjectArray.cls Private Class_Objects() As ObjectPrivate Sub Class_Initialize() ReDim Class_Objects(0) End SubPrivate Sub Class_Terminate() Erase Class_Objects End SubPublic Function CNew(ByRef CItem As Object) As Long CNew = UBound(Class_Objects) + 1 ReDim Preserve Class_Objects(CNew) Set Class_Objects(CNew) = CItem Class_Objects(CNew).index = CNew End FunctionPublic Function CItem(ByVal index As Long) As Object Set CItem = Class_Objects(index) End Function
看看是否符合你的要求: Option Explicit 'in Form Private WithEvents CExample As Class_Example Private CArray As New Class_ObjectArrayPrivate Sub Form_Load() Dim i As Long Set CExample = New Class_Example For i = 1 To 3 CArray.CNew CExample Next i End SubPrivate Sub Form_Unload(Cancel As Integer) Set CExample = Nothing End SubPrivate Sub Form_DblClick() CArray.CItem(2).Raise 2 End SubPrivate Sub CExample_CEvent(ByVal index As Long) MsgBox index End Sub Option Explicit'Class_Example.cls 'Public index As LongPublic Event CEvent(ByVal index As Long)Public Function Raise(ByVal mindex As Long) RaiseEvent CEvent(mindex) End Function Option Explicit'Class_ObjectArray.cls Private Class_Objects() As Object Private Sub Class_Initialize() ReDim Class_Objects(0) End SubPrivate Sub Class_Terminate() Erase Class_Objects End SubPublic Function CNew(ByRef CItem As Object) As Long CNew = UBound(Class_Objects) + 1 ReDim Preserve Class_Objects(CNew) Set Class_Objects(CNew) = CItem 'Class_Objects(CNew).index = CNew End FunctionPublic Function CItem(ByVal index As Long) As Object Set CItem = Class_Objects(index) End Function对比一下: Private Sub Form_Load() Dim i As Long For i = 1 To 3 Set CExample = New Class_Example CArray.CNew CExample Next i End Sub 和: Private Sub Form_Load() Dim i As Long Set CExample = New Class_Example For i = 1 To 3 CArray.CNew CExample Next i End Sub 看看有什么不同
在类模块IEventHandler(事件接口)中Option ExplicitPublic Sub FireEvent()
End Sub在类模块MyObjects(集合类)中Option ExplicitImplements IEventHandlerPublic Event ObjectEvent()Private m_Col As New CollectionPublic Sub Add(objItem As ObjectItem, Optional ByVal Key As String)
objItem.EventHandler = Me
If Len(Key) Then
m_Col.Add objItem, Key
Else
m_Col.Add objItem
End If
End SubPrivate Sub IEventHandler_FireEvent()
RaiseEvent ObjectEvent
End Sub'其他的代码略...在类模块ObjectItem(要处理的对象)Option ExplicitPrivate m_EventHandler As IEventHandlerFriend Property Let EventHandler(ByVal Value As IEventHandler)
Set m_EventHandler = Value
End Property'Test方法通知实现这个接口的对象
Public Sub Test()
m_EventHandler.FireEvent
End Sub使用时Option ExplicitPrivate WithEvents mObjects As MyObjectsPrivate Sub Command1_Click()
Dim o As ObjectItem
If mObjects Is Nothing Then Set mObjects = New MyObjects
Set o = New ObjectItem
mObjects.Add o
o.TestEnd SubPrivate Sub mObjects_ObjectEvent()
MsgBox "OK"
End Sub
新建一个普通工程,添加一个窗体,3个类模块:类模块IEvents:
Option Explicit'interface IEventsPublic Sub Event1()
End SubPublic Sub Event2(ByVal Param As Integer)
End Sub类模块IYourObject:
Option Explicit
'interface IYourObjectPublic Property Get YourProp() As String
End PropertyPublic Sub YourSub(ByVal i As Integer)
End SubPublic Sub SetEventHandler(EH As IEvents)
End Sub类模块CYourObject:
'CYourObject - implements the IYourObject interface
Option Explicit
Implements IYourObject
Dim m_Events As IEvents
Private mYourProp As StringPublic Property Get YourProp() As String
YourProp = IYourObject.YourProp
End Property
Public Sub YourSub(ByVal i As Integer)
IYourObject_YourSub i
End SubPublic Sub SetEventHandler(EH As IEvents)
IYourObject.SetEventHandler EH
End SubPrivate Sub Class_Initialize()
mYourProp = "this is test"
End SubPrivate Sub IYourObject_SetEventHandler(EH As IEvents)
Set m_Events = EH
End SubPrivate Property Get IYourObject_YourProp() As String
'raise an event
IYourObject_YourProp = mYourProp
m_Events.Event1
End PropertyPrivate Sub IYourObject_YourSub(ByVal i As Integer)
' raise an event
m_Events.Event2 i
End Sub窗体:
Option Explicit
Implements IEventsDim MyClassObj As IYourObjectPrivate Sub Command1_Click()
MsgBox MyClassObj.YourProp
End Sub' IEvents implementation
Public Sub IEvents_Event1()
MsgBox "Raised Event1 !!"
End SubPublic Sub IEvents_Event2(ByVal Param As Integer)
MsgBox "Raised Event2 !!"
End Sub' form code
Private Sub Form_Load()
' create the object
Set MyClassObj = New CYourObject
MyClassObj.SetEventHandler Me
End Sub
只是,事件没有办法传回.那位达人帮我想想办法Option Explicit
'in Form
Private WithEvents CExample As Class_Example
Private CArray As New Class_ObjectArrayPrivate Sub Form_Load()
Dim i As Long
For i = 1 To 3
Set CExample = New Class_Example
CArray.CNew CExample
Next i
End SubPrivate Sub Form_Unload(Cancel As Integer)
Set CExample = Nothing
End SubPrivate Sub Form_DblClick()
CArray.CItem(2).Raise
End SubPrivate Sub CExample_CEvent(ByVal index As Long)
Debug.Print index
End Sub
Option Explicit'Class_Example.cls
Public index As LongPublic Event CEvent(ByVal index As Long)Public Function Raise()
RaiseEvent CEvent(index)
End FunctionOption Explicit
'Class_ObjectArray.cls
Private Class_Objects() As ObjectPrivate Sub Class_Initialize()
ReDim Class_Objects(0)
End SubPrivate Sub Class_Terminate()
Erase Class_Objects
End SubPublic Function CNew(ByRef CItem As Object) As Long
CNew = UBound(Class_Objects) + 1
ReDim Preserve Class_Objects(CNew)
Set Class_Objects(CNew) = CItem
Class_Objects(CNew).index = CNew
End FunctionPublic Function CItem(ByVal index As Long) As Object
Set CItem = Class_Objects(index)
End Function
'--------------------------------------------------------
老大,帮我看看我的方法能不能把事件想办法传回去呀?我写了十几个类,不想一个一个改接口呀,现在用我自己的方法已经可以实现类数组和事件回调了,只是类数组的事件回调有点问题.
fj182(阿花)的方法比较标准,建议楼主认真看看,他就是事件中少传了一个Index参数,这只需为对象加个属性,就可解决。
类集合比类数组更便于组织与维护,是MS推荐的方法。稍加改动就可实现与VB控件数组几乎完全一样的用法。rainstormmaster的办法同样使用了接口类,应该也行,只是没采用事件封装而已。
LZ的方法,本质上有问题,可以产生事件,但不能识别对象的Index,而且事件的发生是在基对象之外,你应该加个接口类。
Option Explicit
'in Form
Private WithEvents CExample As Class_Example
Private CArray As New Class_ObjectArrayPrivate Sub Form_Load()
Dim i As Long
Set CExample = New Class_Example
For i = 1 To 3
CArray.CNew CExample
Next i
End SubPrivate Sub Form_Unload(Cancel As Integer)
Set CExample = Nothing
End SubPrivate Sub Form_DblClick()
CArray.CItem(2).Raise 2
End SubPrivate Sub CExample_CEvent(ByVal index As Long)
MsgBox index
End Sub
Option Explicit'Class_Example.cls
'Public index As LongPublic Event CEvent(ByVal index As Long)Public Function Raise(ByVal mindex As Long)
RaiseEvent CEvent(mindex)
End Function
Option Explicit'Class_ObjectArray.cls
Private Class_Objects() As Object
Private Sub Class_Initialize()
ReDim Class_Objects(0)
End SubPrivate Sub Class_Terminate()
Erase Class_Objects
End SubPublic Function CNew(ByRef CItem As Object) As Long
CNew = UBound(Class_Objects) + 1
ReDim Preserve Class_Objects(CNew)
Set Class_Objects(CNew) = CItem
'Class_Objects(CNew).index = CNew
End FunctionPublic Function CItem(ByVal index As Long) As Object
Set CItem = Class_Objects(index)
End Function对比一下:
Private Sub Form_Load()
Dim i As Long
For i = 1 To 3
Set CExample = New Class_Example
CArray.CNew CExample
Next i
End Sub
和:
Private Sub Form_Load()
Dim i As Long
Set CExample = New Class_Example
For i = 1 To 3
CArray.CNew CExample
Next i
End Sub
看看有什么不同
谢谢各位了.