H
Hendrik W. Hansen
Hi,
I'm having a problem with loading and adding usercontrols dynamically after
CreateChildControls. To be more specific, I have a number of buttons and a
PlaceHolder control. When the user clicks one of the buttons, I want to load
and add a different usercontrol in the click event handler, which of course
occurs after CreateChildControls. In the eventhandler I also write a value
to ViewState, so that I can read that value in the override of
CreateChildControls after a postback and load the proper usercontrol.
It works fine the first time the user clicks a button, and the placeholder
does not contain any controls. However if a control was already loaded in
the CreateChildControls, because it existed before the postback, and I
remove that control and add a new one in the click eventhandler, the events
of the new control does not seem to work in the following postback. Only
after the second postback, the events are working. It seems that if a
control has already been loaded into that position in the controls
collection in the CreateChildControls, a new control loaded and added to
that position is not able register its events to work in the next postback -
don't know if it has something to do with the ViewState of that position has
already been "taken" by another. After the first postback the control is
loaded in the CreateChildControls - the events will not fire, since they did
not get registered properly, but since no control has existed in that
position in the controls collection before in the page cycle, the events
gets registered properly this time. After the second postback, the events
fire as planned.
I could make an if control block in CreateChildControls, that prevented a
control from being loaded into the placeholder, if a control was going to be
loaded at a later stage in a click eventhandler. The problem is that there
is no way of knowing whether a button has been clicked in the
CreateChildControls - this is only possible to know in the eventhandler, and
at that point it's too late, a control has already been loaded into the
position, and events will not work.
Is it really possible, that controls cannot be loaded and added to a
controls collection after CreateChildControls, if they contain postback
eventhandlers? Please let me know if anyone has a solution to this problem..
Here is a sample of my code:
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button load1Btn;
protected System.Web.UI.WebControls.PlaceHolder placeHolder;
protected System.Web.UI.WebControls.Button load2Btn;
override protected void OnInit(EventArgs e)
{
load1Btn.Click += new EventHandler(load1Btn_Click);
load2Btn.Click += new EventHandler(load2Btn_Click);
}
protected override void CreateChildControls()
{
if (ViewState["loadedControl"] is string)
placeHolder.Controls.Add(LoadControl((string)
ViewState["loadedControl"]));
base.CreateChildControls();
}
private void load1Btn_Click(object sender, EventArgs e)
{
ViewState["loadedControl"] = "DynamicControl1.ascx";
if (placeHolder.Controls.Count > 0)
placeHolder.Controls.RemoveAt(0);
placeHolder.Controls.Add(LoadControl("DynamicControl1.ascx"));
}
private void load2Btn_Click(object sender, EventArgs e)
{
ViewState["loadedControl"] = "DynamicControl2.ascx";
if (placeHolder.Controls.Count > 0)
placeHolder.Controls.RemoveAt(0);
placeHolder.Controls.Add(LoadControl("DynamicControl2.ascx"));
}
}
public class DynamicControl1 : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.Label msgLbl;
protected System.Web.UI.WebControls.Button testBtn;
override protected void OnInit(EventArgs e)
{
testBtn.Click += new EventHandler(testBtn_Click);
}
private void testBtn_Click(object sender, EventArgs e)
{
msgLbl.Text = "Hello World!";
}
}
Best regards
Hendrik W. Hansen
I'm having a problem with loading and adding usercontrols dynamically after
CreateChildControls. To be more specific, I have a number of buttons and a
PlaceHolder control. When the user clicks one of the buttons, I want to load
and add a different usercontrol in the click event handler, which of course
occurs after CreateChildControls. In the eventhandler I also write a value
to ViewState, so that I can read that value in the override of
CreateChildControls after a postback and load the proper usercontrol.
It works fine the first time the user clicks a button, and the placeholder
does not contain any controls. However if a control was already loaded in
the CreateChildControls, because it existed before the postback, and I
remove that control and add a new one in the click eventhandler, the events
of the new control does not seem to work in the following postback. Only
after the second postback, the events are working. It seems that if a
control has already been loaded into that position in the controls
collection in the CreateChildControls, a new control loaded and added to
that position is not able register its events to work in the next postback -
don't know if it has something to do with the ViewState of that position has
already been "taken" by another. After the first postback the control is
loaded in the CreateChildControls - the events will not fire, since they did
not get registered properly, but since no control has existed in that
position in the controls collection before in the page cycle, the events
gets registered properly this time. After the second postback, the events
fire as planned.
I could make an if control block in CreateChildControls, that prevented a
control from being loaded into the placeholder, if a control was going to be
loaded at a later stage in a click eventhandler. The problem is that there
is no way of knowing whether a button has been clicked in the
CreateChildControls - this is only possible to know in the eventhandler, and
at that point it's too late, a control has already been loaded into the
position, and events will not work.
Is it really possible, that controls cannot be loaded and added to a
controls collection after CreateChildControls, if they contain postback
eventhandlers? Please let me know if anyone has a solution to this problem..
Here is a sample of my code:
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button load1Btn;
protected System.Web.UI.WebControls.PlaceHolder placeHolder;
protected System.Web.UI.WebControls.Button load2Btn;
override protected void OnInit(EventArgs e)
{
load1Btn.Click += new EventHandler(load1Btn_Click);
load2Btn.Click += new EventHandler(load2Btn_Click);
}
protected override void CreateChildControls()
{
if (ViewState["loadedControl"] is string)
placeHolder.Controls.Add(LoadControl((string)
ViewState["loadedControl"]));
base.CreateChildControls();
}
private void load1Btn_Click(object sender, EventArgs e)
{
ViewState["loadedControl"] = "DynamicControl1.ascx";
if (placeHolder.Controls.Count > 0)
placeHolder.Controls.RemoveAt(0);
placeHolder.Controls.Add(LoadControl("DynamicControl1.ascx"));
}
private void load2Btn_Click(object sender, EventArgs e)
{
ViewState["loadedControl"] = "DynamicControl2.ascx";
if (placeHolder.Controls.Count > 0)
placeHolder.Controls.RemoveAt(0);
placeHolder.Controls.Add(LoadControl("DynamicControl2.ascx"));
}
}
public class DynamicControl1 : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.Label msgLbl;
protected System.Web.UI.WebControls.Button testBtn;
override protected void OnInit(EventArgs e)
{
testBtn.Click += new EventHandler(testBtn_Click);
}
private void testBtn_Click(object sender, EventArgs e)
{
msgLbl.Text = "Hello World!";
}
}
Best regards
Hendrik W. Hansen