Creating EventHandlers on the fly

Hi guys,

I'm kinda stuck here. I'm creating x number of buttons at run-time, no promblem there. These buttons need logic for their click event. That's where I'm stuck. I need to build the code for each eventhandler on the fly, compile and attach them to each button's click event. The problem with the code below is that, the start sub was coded in design-time. I need it to be written, compiled and attached to the button at run-time. What's the use of creating a button on the fly if that button a) Doesn't do anything or b) The eventhandler has to be written beforehand at design-time ?

Below is the code block that I'm using right now:

ProtectedSub Page_Load(ByVal senderAsObject,ByVal eAs System.EventArgs)HandlesMe.Load

Dim countAsInteger

For count = 0To 5

Dim tempButtonAsNew Button

tempButton.ID ="TestButton" & count

tempButton.Text ="TestButton-" & count

AddHandler tempButton.Click,AddressOfMe.Start

Panel1.Controls.Add(tempButton)

Next

EndSub

PublicSub Start(ByVal senderAsObject,ByVal eAs EventArgs)

MsgBox("Name of button goes here")

EndSub

Thank you

Jay

[2605 byte] By [Zorthgo] at [2008-1-10]
# 1

Code Snippet

Public Sub Start(ByVal sender As Object, ByVal e As EventArgs)

Dim Btn as Button = DirectCast(Sender, Button)

MsgBox(Btn.Name)

End Sub

Otherwise the code looks OK. As for your questions B, what "magic" is the program going to do at run-time to determine what the button click should do that you can't figure at designtime?

TaDa at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 2

Maybe I'm missing something here.... Why is it not enough for you to do what you have already supplied for code? (I might change your MsgBox line to MsgBox(CType(sender, Button).Name) instead). It seems to do exactly what you want -- when the dynamically added button is clicked it fires off the Start method which can detect which button is calling it (through the sender argument).

And could you elaborate what you mean by "I need it to be written, compiled and attached to the button at run-time." What conditions do you have that require you to write the code that handles the event dynamically? Isn't there some way you can run pre-written code depending on the button and/or some property of that button?

~DigBoy~ at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 3

Thanks TaDa

Your code snippet works flawlessly. Thanks you for the help, you're my new best friend.

As for the b) argument, each button will perform a diferent query back on the my SQL database. This is not the actual code that I'll be using on my program. In the actual code I won't know how many butons will be created, it will be up to the data in the SQL server. So the program would need to be able to write, compile and attach the code on the fly to the button that was just created. I think the only way to do this will be to use reflection. I don't really know much about it but, I'm going to look into it. If you know of any ways I could do this, a nod at the right direction would be greatly appreciated.

Thanks

Jay

Zorthgo at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 4

Hi Digboy

The reason why I need to write the code on the fly, is because each button will run a different query on the DB. Each button will represent a category within a table. When the user clicks on the button it pulls from the database only records that meet a specific criteria. So although every button will do the same thing (pull records from the database), they all have diferent parameters.

Thanks

Jay

Zorthgo at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 5

So does that mean that you are writing the method's code on the fly or are you just choosing a query on the fly? If just the latter, then maybe you could get by with some form of dynamic query builder -- either on the .NET side given the properties of the tables are generic or pre-known, or you could have a server function that returns the bulk of the query text.

I know that I've built a class that constructed its own Insert,update,delete,select queries based on a few constructor arguments (table name, pk column name, etc.). Could something like that work for you (not to discourage you from attempting to learn reflection)?

~DigBoy~ at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 6

Sounds to me like the query is what needs to be created "on the fly", not the code that calls it. Typically I'd add properties to the control (in this case a Button), that contained it's part of the query. A simple example would be you had two buttons "By Name" and "By ID". I'd add a property "Critera" to my Button class and populate them with:

Code Snippet

ByName.Critera = "BY NAME"

ByID.Criteria = "BY ID"

Private SelectSub(.......)

.

.

.

Dim Qry as string = "SELECT SOMETABLE * ORDER " & btn.Criteria

.

.

.

End Sub

PS. I don't use SQL databases, so my syntax may be off, but you get the idea.
TaDa at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 7
After I replied to Digboy I was driving back home and thinking about it. I thought: wait... I don't need to create the code on the fly, just the querystring. But I din't know how to keep the querystring in memory, except by creating a variable for each button. I love the Idea of adding a property to the existing button. I've never done that before. could you point me in the right direction? How would I go about adding a property to a button?

Thanks guys

Zorthgo at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 8

The good news is that you don't have to add a variable to the button -- it's already there in the form of the Tag property. Tag is a catch-all where you can place any type of object so it can be carried along with the parent object (the button in this case). What you place in the Tag is up to you. It can be as simple as the complete query string or it can be a custom class object that holds the variables that can allow you to construct a query from a template on the fly.

If you are still unsure how you might construct that query you are welcome to post a typical query you might create and point out the variable elements of it. The idea is to form a template that all the tables can plug in to.

~DigBoy~ at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 9

Thanks DigBoy but I've got the querystring covered. The problem that I'm having is that I can't access this tag property on the button. I keep getting an error message saying that 'Tag' is not a member of 'System.Web.UI.WebControls.Button'. Could you tell me what I'm doing wrong when I try to access the tag property. It's probably something silly but I can't see it.

Code Snippet

Dim count As Integer

For count = 0 To 5

Dim tempButton As New Button

tempButton.ID = "TestButton" & count

tempButton.Text = "TestButton-" & count

AddHandler tempButton.Click, AddressOf Me.Start

tempButton.Tag = "This is a test"

Panel1.Controls.Add(tempButton)

Next

Thanks

Jay

Zorthgo at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 10

There's a simple answer to that... There is no Tag property on a web button. This forum is dedicated to non-web VB questions. If someone else wants to chime in with how to attach an object to web control then you might get lucky. However, you might get a faster and more appropriate answer at the ASP forum.

~DigBoy~ at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...
# 11

Oh, Wrong forum. sorry!

Thanks for all the help though. You've helped me alot.

Jay

Zorthgo at 2007-10-3 > top of Msdn Tech,Visual Basic,Visual Basic General...