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:
Protected
Sub
Page_Load(ByVal
senderAs
Object
,ByVal
eAs
System.EventArgs)Handles
Me
.Load
Dim
countAs
Integer
For
count = 0To
5
Dim
tempButtonAs
New
ButtontempButton.ID =
"TestButton"
& counttempButton.Text =
"TestButton-"
& countAddHandler
tempButton.Click,AddressOf
Me
.StartPanel1.Controls.Add(tempButton)
Next
End
Sub
Public
Sub
Start(ByVal
senderAs
Object
,ByVal
eAs
EventArgs)MsgBox(
"Name of button goes here"
)End
Sub
Thank you
Jay
[2605 byte] By [
Zorthgo] at [2008-1-10]
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?
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?
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
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
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)?
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.
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
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.
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
ButtontempButton.ID =
"TestButton"
& counttempButton.Text =
"TestButton-"
& countAddHandler
tempButton.Click, AddressOf
Me
.StarttempButton.Tag =
"This is a test"
Panel1.Controls.Add(tempButton)
Next
Thanks
Jay
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.
Oh, Wrong forum. sorry!
Thanks for all the help though. You've helped me alot.
Jay