How to avoid Initialization of web user control inside aspx? - asp.net

I have an aspx page which contains a web user control as below.
<html>
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server">
<uc1:WebUserControl Visible="false" ID="WebUserControl1" runat="server" />
</asp:PlaceHolder>
<asp:Label ID="Label1" runat="server" Text="This is visible"></asp:Label>
</div>
</form>
</body>
</html>
In the Page_Load method of the above page I am setting the Visible = true/false (based on some condition) for the WebUserControl1. WebUserControl1 contains lots of control itself. But I don't want to initialize the controls inside WebUserControl1. Is there anyway we can avoid initializing the ChildControls of WebUserControl1?

From you description, it sounds like the heavy lifting that is being done in the user control is done in the Init event of the user control. May I suggest moving the heavy lifting out of that event to, possibly, the Load event. Then, as #Brian pointed out, you should be able to check if the control is visible and start the heavy lifting if it is.
Code-Behind for your User Control:
protected void Page_Load(object sender, EventArgs e)
{
if (this.Visible)
{
//do heavy lifting here
}
}
If you don't put some kind of conditions on whether or not you lift, you will always lift.

Controls will be added to the control tree and that can't be avoided unless you add controls dynamically (which can be a pain), but you have to handle the backend logic checking. In your user control code, you need to check for Visible = true when you attempt to process server-side logic, and only process when true.

Related

Hiding Literal control declaratively in header (ASP.NET web forms)

I try to hide some Javascript code in header by just using declarations. The Visible property should be controlled by a setting in web.config (ConfigurationManager.AppSettings["key"]).
However, for some reason setting the Visible property like this has no effect - it is always true:
<head id="Head1" runat="server">
<asp:Literal ID="JSLiteral" runat="server" Mode="PassThrough" Visible='<%# false %>'>
Some JS
</asp:Literal>
</head>
It is probably linked to page life cycle in ASP.NET. It works when setting this property in Page_Load event, but that's not what I want as I need to insert this block to a lot of web applications, and I don't want to recompile all of them.
Any ideas how this could be accomplished with minimal effort in ASP.NET? I don't want to mess around with the JS code, which needs to be added in header - it is code of a third-party.
Thanks in advance and cheers,
Roger
Try the following.
protected void Page_Load(object sender, EventArgs e)
{
Head1.DataBind();
}
What you are using is a DataBinding expression. So DataBind() has to be called.

Updatepanel in ajax always runs page_load Event?

I'm new to ajax and using visual studio 2005 and framework 2.0. A simple Ajax sample always takes to the page load event for a button click. No deployment and all just running in debug mode takes me to the Page_Load event. Don't know what is the problem? I have checked the values of UpdatePanel1.IsInPartialRendering and ScriptManager1.IsInAsyncPostBack which is false.
Here is my code,
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" >
</asp:ScriptManager>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label><br />
<asp:Button ID="Button1" runat="server" Text="PostBack" OnClick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToLongTimeString()+UpdatePanel1.IsInPartialRendering+ScriptManager1.IsInAsyncPostBack;
}
Google and stackoverflow doesnt help me so far. So any kind hearts help me...
Control Inside Update Panel Cause asynchronous postback.
What is Asynchronous Postback?
From Refrence To MSDN
An asynchronous postback behaves much like a synchronous postback. All the server page life-cycle events occur, and view state and form data are preserved. However, in the rendering phase, only the contents of the UpdatePanel control are sent to the browser. The rest of the page remains unchanged.
Now if it cause all event on server than what is the use of Partial Rendering...
Partial-page rendering removes the need for the whole page to be
refreshed as the result of a postback. Instead, only individual
regions of the page that have changed are updated. As a result, users
do not see the whole page reload with every postback, which makes user
interaction with the Web page more seamless
I'm a bit rusty on my Web.forms, but as I recall, that is by design. The Page_Load does fire when an AJAX update panel sends a request to the server.

ViewState is not required to preserve control values so what does it do?

I have a very simply web page with ViewState disabled everywhere:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="test" EnableViewState="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox runat="server" EnableViewState="false"></asp:TextBox>
<asp:DropDownList runat="server" id="mylist" EnableViewState="false">
<asp:ListItem>my item 1</asp:ListItem>
<asp:ListItem>my item 2</asp:ListItem>
<asp:ListItem>my item 3</asp:ListItem>
<asp:ListItem>my item 4</asp:ListItem>
<asp:ListItem>my item 5</asp:ListItem>
<asp:ListItem>my item 6</asp:ListItem>
</asp:DropDownList>
<asp:Button runat="server" Text="click me"/>
</div>
</form>
</body>
</html>
Code behind
public partial class test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Dropdown list value is " + mylist.SelectedValue);
}
}
As you can see, no viewstate is enabled but it does preserve controls values, see here for the running example http://www.yart.com.au/stackoverflow/viewstate/test.aspx
Edit
latr0dectus has somewhat answered my question below. But what's an example where ViewState is required practically? I can't see what you need from the form other than control values.
#Petras: ViewState is not required to preserve control values so what does it
do?
Controls that implements IPostBackDataHandler uses LoadPostData() method to assign to some properties.
Read this article : Understanding ASP.NET View State
It is a common misconception among developers that view state is
somehow responsible for having TextBoxes, CheckBoxes, DropDownLists,
and other Web controls remember their values across postback. This is
not the case, as the values are identified via posted back form field
values, and assigned in the LoadPostData() method for those controls
that implement IPostBackDataHandler.
I'm not really sure what your question is.
View state is used in the page lifecycle. After the page is served it is destroyed on the server. Then the browser posts back it also posts back the viewstate. The server can use this in combination with the posted form values to recreate the previous state of the page and then show the changes.
In some cases even with viewstate disabled certain controls will appear to work as if they have viewstate enabled. This is because some controls have what is called "Control State". It operates almost like viewstate, except it cannot be disabled. This is because some controls would cease to function properly without it.
In the example you posted I think you are observing that the selected value of the dropdown is being posted to the server during postback. Not that it was reconstructed from viewstate.
Im adding this information that I found from the following link:
http://aspnetresources.com/articles/ViewState
What's the moral of this story? You don't always need view state enabled to maintain page state. "When do I need it though? What's it for then?" Glad you asked. The prime candidates for participation in view state are those controls that don't post back with the HTTP form and controls added or populated dynamically.
Scan to that part of the document and you should find what you are looking for.

DropDownList in UpdatePanel

In my project I have placed a dropdownlist in an updatepanel.what I wanted to do is to select a value from dropdownlist and use it in a session.
but whatever I do, it will always give me null value because of not checking "Enable AutoPostBack".and when I do this, it will refresh the page so this isn't what I wanted.
It sounds like you may not be using the UpdatePanel feature properly. If you have the UpdatePanel set to update when children fire events, only the UpdatePanel should refresh, not the entire page. The code below seems to behave similar to what you are seeking. When changing the drop down, only the update panel posts back to the server and when you refresh the page, you can get the value out of the session.
ASPX CODE
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
Current Time: <asp:Label ID="lblTime" runat="server" /><br />
Session Value: <asp:Label ID="lblSessionValue" runat="server" /><br />
<br />
<asp:UpdatePanel ID="upSetSession" runat="server">
<ContentTemplate>
<asp:DropDownList ID="ddlMyList" runat="server"
onselectedindexchanged="ddlMyList_SelectedIndexChanged"
AutoPostBack="true">
<asp:ListItem>Select One</asp:ListItem>
<asp:ListItem>Maybe</asp:ListItem>
<asp:ListItem>Yes</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlMyList"
EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
CODE BEHIND
protected void Page_Load(object sender, EventArgs e)
{
this.lblTime.Text = DateTime.Now.ToShortTimeString();
if (Session["MyValue"] != null)
this.lblSessionValue.Text = Session["MyValue"].ToString();
}
protected void ddlMyList_SelectedIndexChanged(object sender, EventArgs e)
{
Session.Remove("MyValue");
Session.Add("MyValue", this.ddlMyList.SelectedValue);
}
In order to get anything stored to Session, you have to submit it to the server.
Perhaps some more details on why you don't want the UpdatePanel refreshing would be helpful, and what you are trying to accomplish using the value in Session.
EDIT: Based on your comments, it seems to me that the solution would be to store the current .ascx file in Session, and set your DropDownList to have autopostback enabled.
So, on your handling of the "Next" and "Back" buttons, store an indicator for the correct .ascx to Session.
During your postback handling of the dropdownlist event, you could simply ensure that the current .ascx file is still being shown, by checking session for the correct file to show. When the result is returned to the client, nothing will appear to have changed, because the UpdatePanel is smart enough to realize it's the same content, and you will have successfully dealt with the dropdownlist value.
It sounds like you're doing way more work than you need to here. Have you looked into using an ASP.NET Wizard Control? http://msdn.microsoft.com/en-us/magazine/cc163894.aspx or just Google it.
If you still want to do it your way, you have to submit to the server (either with no autopostback + manual submit button click, or by enabling autopostback) since the Session is a server-side concept. HTTP is a stateless protocol, so the only concept of state has to be done outside of HTTP's domain. This means you're stuck storing state on the server (for instance, in the session) or, much more restrictively, on the client's computer (such as in a cookie).
thanks a lot I solved problem by controlling variables in Page_Load event.
If Label1.Text = 1 Then
Dim tempcontrol2 As Control = LoadControl("Page1.ascx")
PlaceHolder1.Controls.Add(tempcontrol2)
ElseIf Label1.Text = 2 Then
Dim tempcontrol2 As Control = LoadControl("Page2.ascx")
PlaceHolder1.Controls.Add(tempcontrol2)
End If
thank u for all answers

Multiple UpdatePanels and state

I have a user control that has multiple update panels
On Page Load, I load a child user control dynamically onto the PlaceHolder (I do this everytime and don't check for postback)
I want to be able to maintain the state of the changes that a user makes in the Child user control. (The child user control has html controls along with asp.net controls and other custom controls).
The child user control loses the state whenever there's a click on the Button A or B that causes the postback. The mode for UpdatePanels have been set to conditional.
In the OnPageLoad,
I load a child control to the PlaceHolderA
This child control has another user control with a lot of JS. A user can potentially make changes in the child control.
When they click on Button A which is a part of the parent control, the OnPageLoad causes the child control to reload causing it to lose the client side changes that a user has made.
I would like to prevent this from happening.
Here's the HTML structure of the ASPX page
<UpdatePanel1>
<UpdatePanelChild1>
<Button A>
<Button B>
</UpdatePanelChild1>
<UpdatePanelChild2>
<PlaceHolderA>
</UpdatePanelChild2>
When dynamically adding controls you need to re-add them everytime your page loads. I've had to tackle similar difficulties and I do this in two ways. Where dynamic fields are added o the fly I will actually add a hidden control to the page before the user clicks to fill it in or add it themselves. By creating this sort of placeholder the system has tim eto start handling viewstate correctly and this preserves the users changes. The second issue that I hear you mentioning is that there might be issues with chich update panel updates. It's fine to have them set to conditional bu tin your code-behind you can also trigger the updates in teh othe rpanels if you need to from code. It's just updatepanel#.update()
alternatively you can also wrap all the update panels in another panel but I advise against this as it wastes resources.
It looks like you're losing the ViewState for your dynamically-added child control.
This is because you're adding it too late in the page lifecycle: the ViewState is loaded before the Page.Load event.
Try adding your child control in Page.Init instead.
You could use a ScriptManager with a form runat server in your control, instead update panels.
This way you dont have the post backs.
Here a good reference: http://www.asp.net/Ajax/Documentation/Live/overview/ScriptManagerOverview.aspx
Greetings.
Josema.
http://www.learning-workshop.com
Blockquote
//Code in your Asp.Net code
<form runat="server" id="form1">
<asp:ScriptManager id="ScriptManager1" runat="server" >
<Services>
<asp:ServiceReference Path="/WebServices/MyService.asmx"/>
</Services>
</asp:ScriptManager>
</form>
<script language="javascript" type="text/javascript">
//call with namespace "WebSite" included
WebSite.WebServices.HelloWorld(EndHelloWorld);
function EndHelloWorld()
{
//do whatever
}
</script>
</form>
Blockquote
//Code in your webservice class
[ScriptService]
public class MyService : System.Web.Services.WebService
{
[WebMethod]
public void HelloWorld()
{
return "Hello world";
}
}
From the script of my page i will do Ajax against my webservice, and the callback EndHelloWorld you could do whatever without losing state.
Hope it helps...
Kind Regards.
Josema.
It looks like you need to remove the nested UpdatePanels. In a structure like this:
<ParentUpdatePanel>
<ChildUpdatePanel1 />
<ChildUpdatePanel2 />
</ParentUpdatePanel />
ALL of the update panels will ALWAYS update, even if the child UpdatePanels are set to conditional, because the parent is actually the one that is updating. So, a postback event in one of the children will cause the parent to update.
Using that type of pattern is bad in general... if you need events from one UpdatePanel to cause updates in another, you should do this:
<asp:UpdatePanel ID="up1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="buttonA" runat="server" />
<asp:Button ID="buttonB" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="up2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Placeholder ID="ph" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="buttonB" EventName="Click" />
</Triggers>
</asp:UpdatePanel>

Resources