accessing control that have been created at runtime
-
Hi. I'm generating table with controls at runtime. How can I get an instance of a certain control at runtime Here is a code sample in C#: TableCell Cell = new TableCell(); TableRow Row = new TableRow(); Label la = new Label(); la.Text = "Action:"; Cell.Controls.Add(la); Row.Cells.Add(Cell); tblDetails.Rows.Add(Row); Cell = new TableCell(); Row = new TableRow(); DropDownList cmbAction = new DropDownList(); cmbAction.ID="cmbAction_"+ID; cmbAction.DataSource = oRecAction; cmbAction.DataTextField = "Action"; cmbAction.DataValueField ="ID"; cmbAction.DataBind(); Cell.Controls.Add(cmbAction); Row.Cells.Add(Cell); tblDetails.Rows.Add(Row); I'm trying to get the value from "cmbAction.SelectedValue". I've tried to use tblDetails.FindControl("cmbAction_"+ID) to get the cotrol but that doesn't work. Can anyone help me?
-
Hi. I'm generating table with controls at runtime. How can I get an instance of a certain control at runtime Here is a code sample in C#: TableCell Cell = new TableCell(); TableRow Row = new TableRow(); Label la = new Label(); la.Text = "Action:"; Cell.Controls.Add(la); Row.Cells.Add(Cell); tblDetails.Rows.Add(Row); Cell = new TableCell(); Row = new TableRow(); DropDownList cmbAction = new DropDownList(); cmbAction.ID="cmbAction_"+ID; cmbAction.DataSource = oRecAction; cmbAction.DataTextField = "Action"; cmbAction.DataValueField ="ID"; cmbAction.DataBind(); Cell.Controls.Add(cmbAction); Row.Cells.Add(Cell); tblDetails.Rows.Add(Row); I'm trying to get the value from "cmbAction.SelectedValue". I've tried to use tblDetails.FindControl("cmbAction_"+ID) to get the cotrol but that doesn't work. Can anyone help me?
You may need to study the lifecycle model to see what happens and in what order - data bindging, control creation, event handling, etc. As controls are created from scratch on each server round trip, everything relies on controls being created with the same ID each time. But if you can get to that point also with you controls created at runtime, then you are working in an very familiar event handling model. The code you have showed looks like it would belong in OnDataBinding() (or an DataBinding eventhandler) which should end up making sure the the CreateChildControls() is not called afterwards (ChildControlsCreated = true). On the postback (which I assume is where you want access to your control) you may not want to rebind to data, and you then recreate all your controls in the CreateChildControls. But remember to also recreate the eventhandlers. In the eventhandler you then rebind if necessary. The whole postback and state tracking of ASP.NET (ViewState, event model etc.) will ensure that you don't even have to worry about FindControl, as you have simply set an event handler on you control. E.g (of the top of my head)
void OnDataBinding()/CreateChildControls() { DropDownLiswt cmbAction = new DropDownList(); cmbAction.SelectedIndexChanged += new EventHandler( cmbAction_IndexChanged ); } ... void IndexChanged( object sender, EventArgs e) { // this is called after all controls have been created and data bound DropDownList dl = (DropDownList)sender; string v = dl.SelectedItem.Value; string t = dl.SelectedItem.Text; ... this.DataBind(); }
Possibly slightly rambling - but it does take a litle bit of studying to figure it out ;) Niels -
You may need to study the lifecycle model to see what happens and in what order - data bindging, control creation, event handling, etc. As controls are created from scratch on each server round trip, everything relies on controls being created with the same ID each time. But if you can get to that point also with you controls created at runtime, then you are working in an very familiar event handling model. The code you have showed looks like it would belong in OnDataBinding() (or an DataBinding eventhandler) which should end up making sure the the CreateChildControls() is not called afterwards (ChildControlsCreated = true). On the postback (which I assume is where you want access to your control) you may not want to rebind to data, and you then recreate all your controls in the CreateChildControls. But remember to also recreate the eventhandlers. In the eventhandler you then rebind if necessary. The whole postback and state tracking of ASP.NET (ViewState, event model etc.) will ensure that you don't even have to worry about FindControl, as you have simply set an event handler on you control. E.g (of the top of my head)
void OnDataBinding()/CreateChildControls() { DropDownLiswt cmbAction = new DropDownList(); cmbAction.SelectedIndexChanged += new EventHandler( cmbAction_IndexChanged ); } ... void IndexChanged( object sender, EventArgs e) { // this is called after all controls have been created and data bound DropDownList dl = (DropDownList)sender; string v = dl.SelectedItem.Value; string t = dl.SelectedItem.Text; ... this.DataBind(); }
Possibly slightly rambling - but it does take a litle bit of studying to figure it out ;) NielsThanks for that. I should have descriped my situation better. I'm creating a kind of wizard an the code I posted earlier is in a function that is called when the user has selected one or more items and has clicked on a button. The next steps shows all the things the user has selected with some extra fields the user has to type in some information including selecting from this cmbAction dropdownlist (or just keeping what is selected default). So if the user selected 3 items in the previos step... 3 dropdownlist will appear with those items. Each dropdownlist is identified with the name "cmbAction_"+[ID of the item]. So before runtime I really don't know the identity of the dropdownlists. I'm trying to get the SelectedValue from the dropdownlists on a button click event so I can save the information Would this be possible with the sulution you've just descriped?
-
Hi. I'm generating table with controls at runtime. How can I get an instance of a certain control at runtime Here is a code sample in C#: TableCell Cell = new TableCell(); TableRow Row = new TableRow(); Label la = new Label(); la.Text = "Action:"; Cell.Controls.Add(la); Row.Cells.Add(Cell); tblDetails.Rows.Add(Row); Cell = new TableCell(); Row = new TableRow(); DropDownList cmbAction = new DropDownList(); cmbAction.ID="cmbAction_"+ID; cmbAction.DataSource = oRecAction; cmbAction.DataTextField = "Action"; cmbAction.DataValueField ="ID"; cmbAction.DataBind(); Cell.Controls.Add(cmbAction); Row.Cells.Add(Cell); tblDetails.Rows.Add(Row); I'm trying to get the value from "cmbAction.SelectedValue". I've tried to use tblDetails.FindControl("cmbAction_"+ID) to get the cotrol but that doesn't work. Can anyone help me?
Run the code and check out the source of the page. You will probably find that the name of the dynamic control is not what you thought it was. When a control is added .Net creates a unique ID which is what you are looking for. if you look at the properties and methods of cmbAction you will see a property for .UniqueID this will give you the ID at runtime. He who laughs last thinks slowest.
-
Thanks for that. I should have descriped my situation better. I'm creating a kind of wizard an the code I posted earlier is in a function that is called when the user has selected one or more items and has clicked on a button. The next steps shows all the things the user has selected with some extra fields the user has to type in some information including selecting from this cmbAction dropdownlist (or just keeping what is selected default). So if the user selected 3 items in the previos step... 3 dropdownlist will appear with those items. Each dropdownlist is identified with the name "cmbAction_"+[ID of the item]. So before runtime I really don't know the identity of the dropdownlists. I'm trying to get the SelectedValue from the dropdownlists on a button click event so I can save the information Would this be possible with the sulution you've just descriped?
I think the solution I have (tried to) described should deal with you problem. I think the key will be to dynamically build the page, send it to the server, and then build the exact same page on the return (postback). And with the exact same ID's (UniqueID). And with the right event handlers hooked up, as I tried to illustrate (even though my code example had cmbAction_IndexChanged in one place and just IndexChanged in another). In order to make sure that you construct the exact same page on the postback, you may have to save some information to the ViewState property. ViewState will let you store simple datatypes as well as composite types as ArrayLists and HashTables. Hope you'll figure it out. As I said, you should study the lifecycle and event models of ASP.NET pages, to see why you have to reconstruct the exact same page in order to handle events. Good luck - and sorry for the delay, Niels