Assigning event handlers to dynamically created controls

A

Alex

Hi there,
I have searched recent messages however I did not find any answers to a very
simple question - is it generally possible to assign an event handler to a
control that has been created during run-time???
Example - I have a form with multipage control on it. I dynamically create
pages and populate them with controls like TextBox(es) and Image(s). How
would I assign an event handler, e.g. Change() to those text boxes? Is it
possible at all in VBA (I use Office XP).

Thanks in advance

Alex
 
A

Alex Ivanov

Basically, there are two ways to do this.
1. Declare variables in a class module using WithEvents keyword for every
control you plan to use
(or one for each class of controls, and assign a needed control to that
variable when you want to handle its events, but this is hard to accomplish)
2. Statically create just one control for each class (textbox, combobox,
etc.) and set its Index property to 0, ie create Control Arrays. Set the
Visible property of these controls to false. At Run Time you can Load
additional controls into arrays as required and Unload them when you are
done. Each Control array will have a single event handler, however you can
test which control raised an event examining Index parameter of the event
handler. Sadly, you can't dynamically create Control Arrays using
WithEvents - it must exist at design time.

HTH,
Alex.
 
A

Alex Ivanov

Hi Alex,
I previously mistakengly posted a reply, but can't see it in my reader for
some reason. Hopefully it won't pop up at all. Here is a corrected one.

Declare variables in a class module using WithEvents keyword for every
control you plan to use
(or one for each class of controls, and assign a needed control to that
variable when you want to handle its events, but this is hard to accomplish)

In previous post I stated that you can create a control array, but sorry,
it's not an option in VBA.
 
A

Alex Ivanov

Alex,
I would not recommend to set up the Followup-To field in your posts. I have
sent you a couple of replies, but could not see them in a newsgroup I've
been subscribed to, word.vba.general and was about to blame MS for filtering
out my messages. If you leave this field blank, the replies would be sent to
all workgroups you cross-posted the message by default, but now I had to
enter all of them manually.

Anyway, look into microsoft.public.office.developer for replies.

Alex.
 
A

Alex

Thanks, Alex.
I have already found out by myself that I have to use WithEvent declared
variables ina class module. Strange that it is not always working by some
reason, i.e. for an Image control I am able to trap DblClick event,
however, for a TextBox declared in the same way I cannot trap Change
event...
Here is some source code, maybe I've made a mistake that I don't see
anymore?
-------------------------------------------------------------------------------
-- Class used to trap Image control DblClick event
-- this class is working and I can use it to get double clicks
-- for myImage
clsImage.cls
....
Option Explicit

Public Event DblClick(ByVal Cancel As MSForms.ReturnBoolean)

' the Image object used for depiction
Private WithEvents myImage As Image

' Assigns new image
Property Set Image(newImage As Image)
If myImage Is Nothing Then
Set myImage = newImage
Else
Set myImage = Nothing
Set myImage = newImage
End If
End Property

' Retrieves current image instance
Property Get Image() As Image
Set Image = myImage
End Property

Private Sub myImage_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
MsgBox "Double click detected!"
End Sub
-------------------------------------------------------------------------------
-- Class I am trying to use to capture TextBox Change() event
-- and this is NOT working :((
clsTextBox.cls
....
' Published events
Public Event Change()

' TextBox to wrap
Private WithEvents myTextBox As TextBox

' Set TextBox reference
Property Set TextBox(newTextBox As Object)
If myTextBox Is Nothing Then
Set myTextBox = newTextBox
Else
' first discard old object
Set myTextBox = Nothing
Set myTextBox = newTextBox
End If
End Property

' Retrieve TextBox reference
Property Get TextBox() As Object
Set TextBox = myTextBox
End Property

Private Sub myTextBox_Change()
MsgBox "Change detected"
End Sub
-------------------------------------------------------------------------------
-- and here is how I instantiate these classes:
'...
' Adds a molecule to the project
Sub Test()
Dim myPage As Page
Dim myId as TextBox
Dim myImage As Image
Dim newTextBox as clsTextBox
Dim newImage As clsImage

' increase number of currently processed entries
iCount = iCount + 1
' add a page for new entry
Set myPage = frmMain.MultiPage1.Pages.Add("page" & iCount, "Entry " & _
iCount)

' add ID text box
Set myId = myPage.Controls.Add("Forms.TextBox.1", "tbId", True)
With myId
.Top = 1
.Left = 1
.Width = 15
End With

' add image thumbnail
Set myImage = myPage.Controls.Add("Forms.Image.1", "imgNewImage", True)
With myImage
.Top = 12
.Left = 18
.BorderStyle = fmBorderStyleSingle
.BackColor = &HFFFFFF
.SpecialEffect = fmSpecialEffectSunken
.Width = 240
.Height = 240
.ControlTipText = "Double-click here to edit the entry"
End With
' wrap new image by own class to trap double clicks
Set newImage = New clsImage
Set newImage.Image = myImage
' wrap Id text box by own class to trap changes
Set newTextBox = new clsTextBox
Set newTextBox.TextBox = myId
' Activate last added page
frmMain.MultiPage1.Value = iCount - 1
End Sub
-------------------------------------------------------------------------------
When I run the procedure, the Image and TextBox appears on the form.
However, double-clicks are trapped by clsImage whilst changes in text box
are not :(((

Regards,

Alex
 
A

Alex

I have made it - just collected all the elements I need (i.e. Image and
TextBox) in one class and now it works! ;)

Regards and thanks

Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top