|
Subject:
|
help understanding the page rendering order
|
|
Posted By:
|
jacob
|
Post Date:
|
12/15/2005 6:39:25 PM
|
Need som help figuring out why I can't add a few buttons to an HtmlForm dynamically as late as the when the PreRender event is triggered and still make them work. It seems like if I add the buttons to the HtmlForm from the constructor everything works fine, but if I try to add them when the PreRender is triggered they don't. Why?
The scenario - During the construction I am setting a few properties, which tell which buttons should be shown, e.g. I set a property SubmitLabel and if it is null the submit button should not be added. Therefore, I would like to add the buttons to the form as late as possible, e.g. in the PreRender. Is this not possible? It seems like there is something wrong with this?
Created the test code underneath...<%@ Page language="c#" AutoEventWireup="true" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<head>
<script runat="server">
HtmlInputButton submit;
public void Page_Load(Object oSender, EventArgs eArg)
{
submit = new HtmlInputButton("submit");
submit.ID = "submitButton";
submit.ServerClick += new EventHandler(submit_ServerClick);
this.PreRender += new EventHandler(test_PreRender);
}
public void submit_ServerClick(object sender, System.EventArgs e)
{
this.Response.Write("ServerClick");
}
public void test_PreRender(object sender, System.EventArgs e)
{
myForm.Controls.Add(submit);
}
</script>
</head>
<body>
<form id="myForm" runat="server" />
</body>
</html>If the red line is put into the constructor instead, it will work, but the above code doesn't. Obviously, it is my understanding of the concept, which is wrong but how?
Is there another way to go about this, i.e. adding the buttons at a late time and triggered automatically from some event? The thing is that the functionality is in a base class, and the developer of the child class should not be bothered with adding the buttons manually.
Thanks a lot, Jacob.
|
|
Reply By:
|
planoie
|
Reply Date:
|
12/16/2005 9:21:20 AM
|
Each time the page class is created the controls collection is empty. When the ASPX file is parsed all the controls that live in the markup are added to the page class' Controls collection.
All page control events (button clicks, etc) are raised somewhere in the middle of the page lifecycle. You are adding the button control towards the end of the page lifecycle after the "RaisePostBackEvents" portion of the lifecycle. Therefore, the click event for your button is never fired (versus just getting ignored).
I've approached these types of problems with this idea: Put everything on the page that you'll need, then regulate those controls based on the page logic. So in your case, put that button on the page right where you'll want it, set visible=False then just make it visible when you need it.
-Peter
|
|
Reply By:
|
jacob
|
Reply Date:
|
12/16/2005 4:26:08 PM
|
Thanks for the explanation and solution, Peter.
However, I still find it odd that it matters when the buttons are added, since the event is fired in the next request; i.e. on the first request/response the form is constructed with all the controls, and after loading, the user click the button (new request). So it seems odd that I can't just put buttons on the form, they render, and then when the user clicks the button it works.
I think I will use the solution you gave me regarding hidding. I temporarily solved the problem by changing the set part of the property SubmitLabel, so when it is set, the buttons are generated as well.
Thanks, Jacob.
|
|
Reply By:
|
jacob
|
Reply Date:
|
12/16/2005 4:29:49 PM
|
Ahhhh, I think I got it! It is because the form is generated on the submit request as well, since it uses postback, right?
Jacob.
|
|
Reply By:
|
planoie
|
Reply Date:
|
12/19/2005 10:34:28 AM
|
Precisely. (Funny, I just recently answered a nearly identical question. Can't remember where though.)
EACH time the page is requested (first request, and each following postback request) the form is constructed. If you add the button late in the page cycle based on a user action, that button won't be in the control hierarchy on the next page cycle (postback). Therefore, its events are never captured.
Using the hidden button, the parsing of the markup puts the button in the control structure there all the time, then you just use it when you want. Granted, this doesn't solve the problem of creating truly dynamic controls at runtime, but I find that most people are looking to solve your kind of problem.
-Peter
|
|
Reply By:
|
jacob
|
Reply Date:
|
12/19/2005 12:51:11 PM
|
Thanks, Peter. BR, Jacob.
|