Dynamically assign handlers (AddHandler/AddressOf)

  • Thread starter Thread starter Nigel V Thomas
  • Start date Start date
N

Nigel V Thomas

Is it possible to dynamically direct a particular control's event to use a
predefined method.

For example.
I have a form which I dynamically add controls to, let's say, TextBox1,
TextBox2 and extBox3 and a module which as 3 routines, Method1, Method2,
Method3

When I dynamically add my controls, eg TextBox4, I want to choose which of
the 3 methods I want mapped to which event.

I was thinking of something like this...

..
..
..
Dim objTextBox1 as new TextBox
dim NameOfRoutine$="Module.Method2"
Form.Controls.Add(objTextBox1)

Call AssignMethodToEvent(objTextBox1.GotFocus, NameOfRoutine$)
..
..
..


Can anyone help me on this? Is this possible?

Nigel
 
Nigel said:
Is it possible to dynamically direct a particular control's event to use a
predefined method.

For example.
I have a form which I dynamically add controls to, let's say, TextBox1,
TextBox2 and extBox3 and a module which as 3 routines, Method1, Method2,
Method3

When I dynamically add my controls, eg TextBox4, I want to choose which of
the 3 methods I want mapped to which event.

I was thinking of something like this...

.
.
.
Dim objTextBox1 as new TextBox
dim NameOfRoutine$="Module.Method2"
Form.Controls.Add(objTextBox1)

Call AssignMethodToEvent(objTextBox1.GotFocus, NameOfRoutine$)
.
.
.


Can anyone help me on this? Is this possible?

Nigel

Yes, you can do this dynamically. Here is an example for a new
"Button1" and a subroutine "SomeClickHandler":

AddHandler Button1.Click, AddressOf SomeClickHandler
 
Nigel said:
Is it possible to dynamically direct a particular control's event to use a
predefined method.

For example.
I have a form which I dynamically add controls to, let's say, TextBox1,
TextBox2 and extBox3 and a module which as 3 routines, Method1, Method2,
Method3

When I dynamically add my controls, eg TextBox4, I want to choose which of
the 3 methods I want mapped to which event.

I was thinking of something like this...

..
..
..
Dim objTextBox1 as new TextBox
dim NameOfRoutine$="Module.Method2"
Form.Controls.Add(objTextBox1)

Call AssignMethodToEvent(objTextBox1.GotFocus, NameOfRoutine$)
..
..
..


Can anyone help me on this? Is this possible?

On what does it depend which method is to be used? If the criterion can
be checked at runtime, use If..Then or Select Case.

In principle, identifiers are used for programmers, not at runtime. Period.

After that period, we have reflection. Though, if it's not the only way
to achieve an aim, it should be avoided (IMO). Therefore my question is, why
do you have an identifier that was of note for the compiler only, at runtime
in a string? Is it stored externally? It's dangerous because the compiler
can't check the validity of the name in the string.
 
Family Tree Mike said:
Yes, you can do this dynamically. Here is an example for a new
"Button1" and a subroutine "SomeClickHandler":

AddHandler Button1.Click, AddressOf SomeClickHandler
Mike, thanks for the reply

Unfortunately, I only know that the Button1.Click event is going to be
handled by 'SomeClickHandler' at runtime. I have a number of
'SomeClickHandlers' and I want the .Click event to use only one. I only know
which one at runtime...
 
Mike, Armin

A little background (long, sorry)...

My app has many (many!) data capture forms. The forms allow the user to
input all sorts of basic infomation, dates, times, text, currency, selections
from dropdown lists and so on. Instead of designing each form manually I have
created a module (minput) which exposes some properties and a method for
input.

For example:
To display a data capture form for a user which prompts for something simple
like a name and password (this is a very simplistic example) I do the
following..

call mInput.AddField(FieldTitle$="Your name",FieldType.Name,DefaultValue$="")
call
mInput.AddField(FieldTitle$="Password",FieldType.Password,DefaultValue$="")
call mInput.AddField(FieldTitle$="D.O.B.",FieldType.Date,DefaultValue$="")
I can group the fields across Tabs on a TabControl, add tooltips, reasons
for validation failure and many more options


I then call mInput.Start which dynamically creates a form and adds the
'fields' to it then displays it for the user to complete along with a OK and
Cancel button. All very simple and works fine. Each input 'field' is actually
a usercontrol based on a textbox, checkbox or combobox, which has basic
validation depending on it's Type (Date, Time, Currency and so on)

I check the result of mInput and if False I discard the inputs and if True I
process them. Simple

Now I need to step it up a gear. Some 'fields' (remember they are my
usercontrols) require 'extra validation' not catered for in the basic
control, for example to check if the input is in a database lookup list. A
specific example is to check against a database record to see if a customer
is restriced or not.

My problem is how to perform this 'extra validation' I was hoping I could
write the 'extra validation' routine then some how (addhandler, addressOf?)
get the 'field' to use the external routine for validation, returning
True/False/Reason for failure. The problem is that I need to indicate to the
'field' what routine to use for the 'extra validation' at runtime, for
example...

minput.Addfield(Fieldname$="Town",FieldType.Text,Default$="",AddressOf
ExtraValidation)

Maybe there is another approach.

Thanks for your patience
 
Nigel said:
My problem is how to perform this 'extra validation' I was hoping I could
write the 'extra validation' routine then some how (addhandler, addressOf?)
get the 'field' to use the external routine for validation, returning
True/False/Reason for failure. The problem is that I need to indicate to the
'field' what routine to use for the 'extra validation' at runtime, for
example...

minput.Addfield(Fieldname$="Town",FieldType.Text,Default$="",AddressOf
ExtraValidation)

With the Call statement (above) and the $ signs, it looked to me like a foreign langauge
at first sight. :-)

What you need is a delegate:

delegate function MyValidationFunction(input as string) as boolean

mInput class:
sub AddField(......, ValidationFucntion as MyValidationFunction)

Call:
minput.AddField(...., addressof ExtraValidation)
 
Armin Zingler said:
With the Call statement (above) and the $ signs, it looked to me like a foreign langauge
at first sight. :-)

What you need is a delegate:

delegate function MyValidationFunction(input as string) as boolean

mInput class:
sub AddField(......, ValidationFucntion as MyValidationFunction)

Call:
minput.AddField(...., addressof ExtraValidation)




--
Armin


.
Armin

Thanks for the reply. I'm a bit out of my depth with delegates, spent the
afternoon researching, but still a bit vague.

In your example, how do I get the validation event of my UserControl to call
the delegate function?

I have a solution using CallByName where I pass the name of the validation
routine in the Tag of my usercontrol. Are Delegates preferable?

Nigel
 
Nigel said:
Thanks for the reply. I'm a bit out of my depth with delegates, spent the
afternoon researching, but still a bit vague.

In your example, how do I get the validation event of my UserControl to call
the delegate function?

Somewhere you probably store the delegate. If the variable is named "ValidationFucntion"
like the parameter in the AddField method above, you call the method just by typing

result = ValidationFucntion(value)
I have a solution using CallByName where I pass the name of the validation
routine in the Tag of my usercontrol. Are Delegates preferable?

Yes, absolutely. CallByName uses reflection. This is dangerous as mentioned
before and it is slow. Always have the compiler do as many checks as possible.
 
Back
Top