I have a dynamic range of OptionButtons within a frame in a Userform. The number of OptionButtons vary according to number of columns in a table. Each button is labeled according the column label. When a person selects an option I need a ListBox to be populated with the items found within that table column. Populating the option buttons and ListBox is easy enough. I know how to detect mouse down events on known Userformobjects. But the buttons exist only through coding and vary. How do I detect MouseDown on an object that doesn't actually exist? I have tried the code for creating a MouseDown Class for a Frame
You need to wrap your controls in a class module - say, DynamicOptionButton
:
Option Explicit
Private WithEvents ControlEvents As MSForms.OptionButton
Public Sub Initialize(ByVal ctrl As MSForms.OptionButton)
If Not ControlEvents Is Nothing Then ThrowAlreadyInitialized
Set ControlEvents = ctrl
End Property
Private Property Get AsControl() As MSForms.Control
Set AsControl = ControlEvents
End Property
Private Sub ThrowAlreadyInitialized()
Err.Raise 5, TypeName(Me), "Invalid Operation: This control is already initialized."
End Sub
Private Sub ControlEvents_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim parentForm As UserForm1 'todo: use your actual UserForm subtype
Set parentForm = AsControl.Parent
'handle mousedown here.
End Sub
When you create the dynamic controls, you'll want a module-level Collection
to hold the DynamicOptionButton
instances - otherwise they'll go out of scope when End Sub
is reached, and you'll never be able to handle any of their events.
Private DynamicControls As Collection
Private Sub Class_Initialize()
Set DynamicControls = New Collection
'todo invoke CreateOptionButton
End Sub
Private Sub CreateOptionButton() 'todo parameterize
Dim ctrl As MSForms.OptionButton
Set ctrl = Me.Controls.Add(...)
Dim wrapper As DynamicOptionButton
Set wrapper = New DynamicOptionButton
wrapper.Initialize ctrl
DynamicControls.Add wrapper
End Sub