从运行时创建的控件中侦听事件

时间:2018-03-27 20:53:32

标签: vba excel-vba events event-handling excel

我创建了一个类,当一个UserForm作为参数时,它应该在该用户窗体上放置一个控件并监听它的事件。

简化类是:

eventsTestItem class

Private WithEvents formControl As MSForms.Image
Private parentUF As MSForms.UserForm

Private Sub formControl_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
MsgBox "clicked"
End Sub

Public Property Let Visible(ByVal makeVisible As Boolean)
    '(make) and show if true, otherwise delete
    If makeVisible Then
        ImageBase.Visible = True
    Else
        ParentForm.Controls.Remove ImageBase.Name
    End If
End Property

Public Property Set ItemParentUF(ByVal value As MSForms.UserForm)
    Set parentUF = value
End Property

Private Property Get ParentForm() As MSForms.UserForm
    If parentUF Is Nothing Then
        Err.Description = "Grid Item Requires parent Form to be set"
        Err.Raise 5                              'no parent uf set yet
    Else
        Set ParentForm = parentUF
    End If
End Property

Public Property Get ImageBase() As MSForms.Image
    If formControl Is Nothing Then
        Set formControl = ParentForm.Controls.Add("Forms.Image.1", Name:="TestImage", Visible:=False)
    End If
    Set ImageBase = formControl
End Property

Public Property Set ImageBase(value As MSForms.Image)
    Set formControl = value
End Property

我期望制作一个Image控件,我可以调整其中的事件。

为了测试,我使用以下代码创建了一个空的userform:

Private Sub UserForm_Initialize()

    Dim testItem As New eventsTestItem  'create event listener class
    With testItem
        Set .ItemParentUF = Me   'tell it which userform to create a new control on
        .Visible = True     'Make and display the control
    End With
    Debug.Assert Me.Controls.Count = 1 'check if control added

End Sub

哪个运行没有错误(即创建了控件,它也在表单上可见)。

但是事件监听器没有按预期工作,单击图像时应该引发事件。我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

正在发生的事情是,testItem一旦表单初始化就会超出范围。

Private Sub UserForm_Initialize()

    Dim testItem As New eventsTestItem  'procedure-scoped
    '...

End Sub

将该声明移至模块级,以使其位于适当的范围内。

答案 1 :(得分:2)

testItem返回时,UserForm_Initialize实例将被处理掉。

要使其工作,您必须将实例存储在过程范围之外。例如,您可以将其声明为Static以使实例保持活动状态:

Private Sub UserForm_Click()
    Static testItem As Class1

    Set testItem = New Class1  'create event listener class
    With testItem
        Set .ItemParentUF = Me   'tell it which userform to create a new control on
        .Visible = True     'Make and display the control
    End With
    Debug.Assert Me.Controls.Count = 1 'check if control added

End Sub