Problem with ButtonEvents on dynamic UserContols
-
Hello There! I have a usercontrol named A that displays data from a database. I create a dynamic number of usercontrols depending on the number of hits from the database given a certain critera. If I receive 4 datasets from the database I create 4 usercontrols and so on… These Usercontrols contains repeater objects displaying the data aswell as a button that interact with the data. Im now experiencing some major problems to get these buttons to fire once pressed. I do believe I have done it the right way. Usercontrol A 1. Initialize 2. declare Click method
private void InitializeComponent() { this.OpenButton.Click += new System.EventHandler(this.Open_Click); this.Load += new System.EventHandler(this.Page_Load); }
protected void OpenButton_Click(object sender, System.EventArgs e) { //Log activity }
It works perfect using static usercontrols, but not in this dynamic case. It wont even enter the OpenButton_click method in debug mode. Is the EventHandler passing the event to the main app or what is happening.?!? Nothing what so ever happens.. Please help me Experts-Number-One, you are my only hope…. /Peter -
Hello There! I have a usercontrol named A that displays data from a database. I create a dynamic number of usercontrols depending on the number of hits from the database given a certain critera. If I receive 4 datasets from the database I create 4 usercontrols and so on… These Usercontrols contains repeater objects displaying the data aswell as a button that interact with the data. Im now experiencing some major problems to get these buttons to fire once pressed. I do believe I have done it the right way. Usercontrol A 1. Initialize 2. declare Click method
private void InitializeComponent() { this.OpenButton.Click += new System.EventHandler(this.Open_Click); this.Load += new System.EventHandler(this.Page_Load); }
protected void OpenButton_Click(object sender, System.EventArgs e) { //Log activity }
It works perfect using static usercontrols, but not in this dynamic case. It wont even enter the OpenButton_click method in debug mode. Is the EventHandler passing the event to the main app or what is happening.?!? Nothing what so ever happens.. Please help me Experts-Number-One, you are my only hope…. /PeterSee, Recall that the framework create the controls tree only for static controls - this is why the event of the dynamic controls could not reached there targets when the page is posted back - so this is your job, as i describe in a minute. The problem is that the page controls tree is built before the page load - and events that should be fired target to controls resolved in that stage. Hence if your dynamic controls are not existed in this level - WITH THE SAME ID AS THEY HAD IN THE PREVIOUS POSTBACK - the events will not be fired. So, a good solution will be: 1 - When you create the controls assigned them a unique id. Aparantly you will do it in the Page_Load, you should do it only if the page was not post bask. Dont forget to add you controls to the Controls Collection of their container. For example - if you add these controls directly on the form - Write: Page.Controls.Add(...your control here). Page_load... - if not post back - Create the control - Assigned the created control a unique id - Add the created control to its container "Controls" collection. 2 - When you create these controls - put some information in the ViewState so you can rebuild these controls when the page will be posted-back: - ViewState[some key]=information. The information should be encoded in a way that can describe you in the next step what controls were existed before the post back. 3 - Override the TrackViewState method of the page and rebuild the dynamic part of your page using the information you saved in the ViewState. Again dont forget to add these dynamic created controls to your Controls collection. That is all! If the dynamic controls that you are creating are always the same (obviously they are not) you could be satisfied with the Page_Load part without checking the PostBack status. Best regards, e-laj
-
See, Recall that the framework create the controls tree only for static controls - this is why the event of the dynamic controls could not reached there targets when the page is posted back - so this is your job, as i describe in a minute. The problem is that the page controls tree is built before the page load - and events that should be fired target to controls resolved in that stage. Hence if your dynamic controls are not existed in this level - WITH THE SAME ID AS THEY HAD IN THE PREVIOUS POSTBACK - the events will not be fired. So, a good solution will be: 1 - When you create the controls assigned them a unique id. Aparantly you will do it in the Page_Load, you should do it only if the page was not post bask. Dont forget to add you controls to the Controls Collection of their container. For example - if you add these controls directly on the form - Write: Page.Controls.Add(...your control here). Page_load... - if not post back - Create the control - Assigned the created control a unique id - Add the created control to its container "Controls" collection. 2 - When you create these controls - put some information in the ViewState so you can rebuild these controls when the page will be posted-back: - ViewState[some key]=information. The information should be encoded in a way that can describe you in the next step what controls were existed before the post back. 3 - Override the TrackViewState method of the page and rebuild the dynamic part of your page using the information you saved in the ViewState. Again dont forget to add these dynamic created controls to your Controls collection. That is all! If the dynamic controls that you are creating are always the same (obviously they are not) you could be satisfied with the Page_Load part without checking the PostBack status. Best regards, e-laj
-
See, Recall that the framework create the controls tree only for static controls - this is why the event of the dynamic controls could not reached there targets when the page is posted back - so this is your job, as i describe in a minute. The problem is that the page controls tree is built before the page load - and events that should be fired target to controls resolved in that stage. Hence if your dynamic controls are not existed in this level - WITH THE SAME ID AS THEY HAD IN THE PREVIOUS POSTBACK - the events will not be fired. So, a good solution will be: 1 - When you create the controls assigned them a unique id. Aparantly you will do it in the Page_Load, you should do it only if the page was not post bask. Dont forget to add you controls to the Controls Collection of their container. For example - if you add these controls directly on the form - Write: Page.Controls.Add(...your control here). Page_load... - if not post back - Create the control - Assigned the created control a unique id - Add the created control to its container "Controls" collection. 2 - When you create these controls - put some information in the ViewState so you can rebuild these controls when the page will be posted-back: - ViewState[some key]=information. The information should be encoded in a way that can describe you in the next step what controls were existed before the post back. 3 - Override the TrackViewState method of the page and rebuild the dynamic part of your page using the information you saved in the ViewState. Again dont forget to add these dynamic created controls to your Controls collection. That is all! If the dynamic controls that you are creating are always the same (obviously they are not) you could be satisfied with the Page_Load part without checking the PostBack status. Best regards, e-laj
Thanks for the reply and detailed answer e-laj! I have been away for a couple of days so I havn't been able to reply until now. Anyway I have made some progress: 1. I load the controls in Page_Load and assign them unique ids within not PagePostBack. 2. I put the control into the viewstate (to load when page is post back) The events wont fire the first time but the second time they do. It still seems to be something wiht the lifecycle. Could you explain some more about the TrackViewState?
if(!Page.IsPostBack) { RequestDataFromPostMessage(); Domain [] domainCollection = GetInformationFromWebSevice() _//Length=How many usercontrols to create_ domains=domainCollection.Length; ViewState["domains"]=domains; DomainControls = new DomainControl[domains]; for(int i=0;i domains;i++) { DomainControls[i]=(DomainControl)LoadControl "DomainControl.ascx"); _//Init the usercontrols within the specific usercontrols, the controls actually raising the events_ DomainControls[i].InitSubDomainData(.......); _//unique ID_ DomainControls[i].ID=i.ToString(); Session["DomainControl"+i.ToString()]=(Control)DomainControls[i]; placeHolder1.Controls.Add(DomainControls[i]); } } _//if post back_ else { domains = (int)ViewState["domains"]; DomainControl dControl = new DomainControl(); for(int i=0;i The debugger crahses in the Onclick event method in the usercontrol while debugging. `protected void Open_Click(object sender, System.EventArgs e) { ....do something }` Any suggestions? Thanks!
-
Thanks for the reply and detailed answer e-laj! I have been away for a couple of days so I havn't been able to reply until now. Anyway I have made some progress: 1. I load the controls in Page_Load and assign them unique ids within not PagePostBack. 2. I put the control into the viewstate (to load when page is post back) The events wont fire the first time but the second time they do. It still seems to be something wiht the lifecycle. Could you explain some more about the TrackViewState?
if(!Page.IsPostBack) { RequestDataFromPostMessage(); Domain [] domainCollection = GetInformationFromWebSevice() _//Length=How many usercontrols to create_ domains=domainCollection.Length; ViewState["domains"]=domains; DomainControls = new DomainControl[domains]; for(int i=0;i domains;i++) { DomainControls[i]=(DomainControl)LoadControl "DomainControl.ascx"); _//Init the usercontrols within the specific usercontrols, the controls actually raising the events_ DomainControls[i].InitSubDomainData(.......); _//unique ID_ DomainControls[i].ID=i.ToString(); Session["DomainControl"+i.ToString()]=(Control)DomainControls[i]; placeHolder1.Controls.Add(DomainControls[i]); } } _//if post back_ else { domains = (int)ViewState["domains"]; DomainControl dControl = new DomainControl(); for(int i=0;i The debugger crahses in the Onclick event method in the usercontrol while debugging. `protected void Open_Click(object sender, System.EventArgs e) { ....do something }` Any suggestions? Thanks!
Sorry - I have a little mistake, well i implement dynamic control creation long time ago - i forgot an important point. You should override the LoadViewState instead of TrackViewState. The TrackViewState is executed before the view state is populated with the previous value, LoadViewState is the right point to initialize dynamic controls according to view state values - in this point the view state has its previous values. Here is a full running example. In this example you can create dynamic buttons and executes their events. I wrote this example for you and any other who may need it. The DynamicExample.aspx ======================= <%@ Page Language="C#" AutoEventWireup="true" CodeFile="DynamicExample.aspx.cs" Inherits="_Default" %> Untitled Page
buttons
Click Message:
Command Message:
The DynamicExample.aspx.cs ========================== /******************************************************************************* * * Filename: DynamicExample.cs * * Class: DynamicExample * * Creation Date: 06/Oct/2006 * * Update list: * ----------- * 1) Date: * Description: * * Writer: Ilan Amoyal (e-laj) * ******************************************************************************/ using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) {