VBA:在用户窗体上使用 WithEvents

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1083603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 09:53:56  来源:igfitidea点击:

VBA: Using WithEvents on UserForms

formsvbaeventsevent-handlingms-word

提问by user51498

I have a Word userform with 60+ controls of varying types. I would like to evaluate the form every time a control_change event is triggered and change the enabled state of the form's submit button. However, I really don't want to write and maintain 60 on change event handlers.

我有一个 Word 用户窗体,其中包含 60 多个不同类型的控件。我想在每次触发 control_change 事件并更改表单提交按钮的启用状态时评估表单。但是,我真的不想在更改事件处理程序上编写和维护 60。

回答by Gary McGill

You can create an event-sink class that will contain the event-handling code for all of your controls of a particular type.

您可以创建一个事件接收器类,该类将包含特定类型的所有控件的事件处理代码。

For example, create the a class called TextBoxEventHandleras follows:

例如,创建一个名为TextBoxEventHandler如下的类:

Private WithEvents m_oTextBox as TextBox

Public Property Set TextBox(ByVal oTextBox as TextBox)
    Set m_oTextBox = oTextBox
End Property

Private Sub m_oTextBox_Change()
    ' Do something
End Sub

Now you need to create & hook up an instance of that class for each control of the appropriate type on your form:

现在,您需要为表单上适当类型的每个控件创建并连接该类的实例:

Private m_oCollectionOfEventHandlers As Collection

Private Sub UserForm_Initialise()

    Set m_oCollectionOfEventHandlers = New Collection

    Dim oControl As Control
    For Each oControl In Me.Controls

        If TypeName(oControl) = "TextBox" Then

            Dim oEventHandler As TextBoxEventHandler
            Set oEventHandler = New TextBoxEventHandler

            Set oEventHandler.TextBox = oControl

            m_oCollectionOfEventHandlers.Add oEventHandler

        End If

    Next oControl

End Sub

Note that the reason you need to add the event handler instances to a collection is simply to ensure that they remain referenced and thus don't get discarded by the garbage collector before you're finished with them.

请注意,您需要将事件处理程序实例添加到集合中的原因只是为了确保它们保持被引用,因此在您完成它们之前不会被垃圾收集器丢弃。

Clearly this technique can be extended to deal with other types of control. You could either have separate event handler classes for each type, or you could use a single class that has a member variable (and associated property & event handler) for each of the control types you need to handle.

显然,这种技术可以扩展到处理其他类型的控制。您可以为每种类型使用单独的事件处理程序类,也可以使用单个类,该类为您需要处理的每种控件类型提供一个成员变量(以及相关联的属性和事件处理程序)。

回答by Daniel Rikowski

In that case you have few options, because event handlers cannot be shared in VBA/VB6

在这种情况下,您几乎没有选择,因为无法在 VBA/VB6 中共享事件处理程序

Option 1:Use a central handling function which is called from every event handler.

选项 1:使用从每个事件处理程序调用的中央处理函数。

Sub Control1_ChangeEvent()
  CommonChangeEvent // Just call the common handler, parameters as needed
End Sub

Sub Control2_ChangeEvent()
  CommonChangeEvent
End Sub
...
Sub CommonChangeEvent(/* Add necessary parameters */)
  //Do the heavy lifting here
End Sub

Option 2:Organize your controls in control arrays.

选项 2:在控件数组中组织控件。

Sub TextBox_ChangeEvent(Index As Integer)
  CommonChangeEvent
End Sub

Sub OtherControlType_ChangeEvent(Index As Integer)
  CommonChangeEvent
End Sub

Combining both options your total event handler count will shrink considerably and the remaining handlers are just brainless stubs for the one true event handler.

结合这两个选项,您的事件处理程序总数将大大减少,而其余的处理程序只是一个真正事件处理程序的无脑存根。