Showing posts with label updatepanel. Show all posts
Showing posts with label updatepanel. Show all posts

Wednesday, March 28, 2012

Programatically add UserControls that Contain an UpdatePanel

In the release notes for the latest release it states that you can programatically add UpdatePanels now. I have a user control (ascx) that contains an UpdatePanel and a Timer to refresh the panel. When I add more than one of these controls to the page programatically the first refresh of one of the UpdatePanels blanks out all of the data in all of ascx controls. When I add the controls to the page in the aspx code everything works fine. I need to add them programatically since the number of them is configurable. I have the ScriptManager control on the page with partial refresh enabled. Is there something special I need to do when I add these controls programatically?

UserControl

<%@dotnet.itags.org. Control Language="C#" AutoEventWireup="true" Codebehind="DataPart.ascx.cs" Inherits="MS.Support.KnowledgeManagement.VisualKb.DataPart"
EnableViewState="false" %>
<div class="dataPart">
<div id="divHeader" class="dataPartHeader" runat="server">
<img alt="Collapse" style='float: right' src='images/Collapse.gif' title='Collapse'
onclick="ExpandCollapse(this,this.parentElement.parentElement.children(1))" />
<asp:Label ID="lblHeader" runat="server"></asp:Label>
</div>
<div id="divBody" class="dataPartBody" runat="server">
<asp:UpdatePanel ID="divUpdate" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<vkb:VkbBulletedList ID="blItems" runat="server" BulletStyle='disc' DisplayMode='HyperLink'
CssClass="dataPartList" NewIndicatorFontColor="red">
</vkb:VkbBulletedList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="timerRefresh" />
</Triggers>
</asp:UpdatePanel>
<div style='text-align: center; width: 100%'>
<asp:HyperLink ID="lnkViewAll" runat="server" CssClass="dataPartLink">View All</asp:HyperLink>
</div>
</div>
</div>
<asp:XmlDataSource ID="xmlDataSource" runat="server" XPath="descendant::Items/Item"
EnableCaching="false" EnableViewState="False"></asp:XmlDataSource>
<asp:Timer ID="timerRefresh" OnTick="timerRefresh_Tick" runat="server">
</asp:Timer>

Code to add ascx to page

dp = Page.LoadControl("DataPart.ascx") as DataPart;
dp.DataType = "Article";
dp.HeaderColor = Color.LightGray;
dp.HeaderFontColor = Color.Black;
dp.HeaderText = nodes.Current.GetAttribute("Name", String.Empty);
dp.CategoryId = Convert.ToInt32(nodes.Current.GetAttribute("Id", String.Empty));
dp.BodyColor = Color.WhiteSmoke;
dp.EnableRefresh = false;
dp.XmlData = nodes.Current.SelectSingleNode("Items") != null ? nodes.Current.SelectSingleNode("Items").OuterXml : "<Items />";
td.Controls.Add(dp);

I tried a simple example just using a RadioButtonList against XML data source and everything seemed to work fine when adding dynamically. What's in the VkbBulletedList control?
Its just an override of the BulletedList control to add some custom text to each bulleted item.

Programatically adding UpdatePanel?

I want to programatically add an updatepanel control on a button click.

I tried adding a reference to Microsoft.Web.Atlas.dll and then creatinga System.Web.UI.UpdatePanel control but the app does not compile - withnamespace does not exist error.

Does anyone know what I should be doing or if this is possible at all?

Thanks !

you would need to import the following

Imports Microsoft.Web.UI

Then, you can create an instance of the UpdatePanel like this:

Dim UP As New UpdatePanel

Hope this works for you.


Thanks it works ... I was using System.Web.UI which was the problem
Now that I have this I'm trying to add content to the updatepanel.

I can set most of the properties, add triggers without problems.

However when I try to execute it - it gives an error saying "A ContentTemplate must be specified".

Whats the easist way to do this. I haven't found any documentation on programatically adding a contenttemplate.

Any help would be greatly appreciated!
I'm looking for the same thing myself and haven't found any answers.
You'll need to create a class that implements ITemplate, create an instance of that and set the content template property to that instance.

try this

protected

overridevoid OnInit(EventArgs e)

{

updatePanel.ContentTemplate =

newCompiledTemplateBuilder

(

newBuildTemplateMethod(CreateAtlasUpdateContent));

}

public

void CreateAtlasUpdateContent(Control container)

{

container.Controls.Add(yourcontrol);

}


dont know if this will come in handy with anyone but what i did to get around the template error was

have a class with the following:

PublicClass AjaxControl :Inherits Microsoft.Web.UI.UpdatePanelProtectedOverridesSub OnInit(ByVal eAs System.EventArgs)Me.ContentTemplate =New TemplateBuilderMyBase.OnInit(e)EndSubEndClass

Then whenever i needed to create a control that was surrounded by the update panel i would inherit this class and could just then put me.controls.add() as usual.

probs useless to you all, but works for me :)


Even if you got past the coding issues, you still can't add an UpdatePanel once InitComplete has fired (which is pretty early in the lifecycle) so you're not going to be able to accomplish what you set out to do, which I think was to add an UpdatePanel dynamically.

HTH

Has anyone been able to dynamically add an UpdatePanel to a page?

I got so far - and then I got the error:

"The UpdatePanel 'panel1'was not present when the page's InitComplete event was raised."

Is there any way around this?

Wade.

programatically disable dropdown in Ajax updatepanel

I've searched high and low for what seemed would be a simple and frequently used method to access the properties of a drop down contained in a Ajax UpdatePanel without finding anyone who seems to have needed to do this or who has solved it. Maybe Microsoft decided nobody would ever want to do such a weird thing!

I have users with various permission levels. Depending on their level, on page load I need to disable drop downs which are contained within Ajax Updatepanels.

I can expose the properties of the UpdatePanels themselves but they do not support the enable property, only invisible which is no help.

Anyone know how this is done ?

Thanks

Aren't you able to just set the Enabled property of the appropriate DropDownList's?


Dont depends only on UI elements enable/disable state. Also enusre the User level in server side. Can pls post some code i mean in which point you want to disable the dropdown list.

Use CascadingDropDown control in AJAXControlToolKit

http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx


Hi,

Are you using the AJAX extension version 1.0.61025.0 ?

I'm using this one. The controls inside UpdatePanel can be accessed directly. For instance:

<%@. Page Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server"> protected void Page_Load(object sender, EventArgs e) { DropDownList1.Enabled = false; }</script><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:DropDownList ID="DropDownList1" runat="server"> </asp:DropDownList> </ContentTemplate> </asp:UpdatePanel> </div> </form></body></html>

Programmatical change Label.Text of a set of labels in an UpdatePanel

I write engineering solutions in VB. In most cases they need to operate in both metric and English units of measure so I need to update labels such as °F and °C appropriately. I have a number of labels in an UpdatePanel that need this sort of update. Some need to switch between °F and °C while others betweem feet and meters. Which type of units of measure to use is known at Page_Load so I thought I could just make the Label.IDs meaningful (use lblTemp1, lblTemp2 etc for temperature units) and then update their .Text property based on their ID and the units of measure. I am almost there but I can't seem to gain access to the Text property once I ahve found a Label's whose text I want to change.

Dim iAsInteger = 0

Dim myLabelAs Label

'controls I want to update are in and UpdatePanel...

ForEach ctrlAs ControlIn UpdatePanel1.Controls'check to nake sure it actually has controls first...
If ctrl.HasControls()Then'cycle through all controls in the UpdatePanel...
For i = 1To ctrl.Controls.Count
'if this is a Label then
IfTypeOf ctrl.Controls(i)Is LabelThen
'if the label ID contains "lblTemp this is a temperature unit and must be updatedIf ctrl.Controls(i).ID.ToString.Contains("lblTemp")Then
'HERE IS WHERE THE PROBLEM EXISTS...'can not gain access to the Text property

myLabel =

CType(ctrl, Label)
If uofm = SIUnitsThen 'metric

myLabel.Text =

"°C"Else

myLabel.Text =

"°F"EndIfEndIfEndIfNextEndIfNext

What error do you get? Can you post your ASP.NET code?

What kind of error you are facing ??

Post it here...


The error message I currently get is due to a casting error in the line.Unable to cast object of type 'System.Web.UI.Control' to type 'System.Web.UI.WebControls.Label'.

myLabel =CType(ctrl, Label)

At this point in the code I have found a control and determined that it is in fact a Label who's Text property I need to change. However there is no Text property for the crtl so I am trying to cast the ctrl as a Label.

Jim

Programmatically adding ASP.net User Control to UpdatePanel

Hi All, I got a real doozy here. I have read hundreds upon hundreds of forum posts and found numerous others who have replicated this problem, but have yet to find a solution. Through testing I have been able to find the cause of the problem, and will describe it here first textually and then through a code example.

The purpose of what I am trying to do is to create a postback-free web application through the use of ASP.net AJAX UpdatePanels and User Controls. When programmatically adding a User Control to a web page through a normal postback everything works fine. All the controls within the user control are registered properly in the page and any update panels included in the user control also work properly. HOWEVER, if instead of using a full postback you use an UpdatePanel and a partial page update of the UpdatePanel the controls do not get registered with the page and events from them do not fire (for instance, a button click event never hits the event breakpoint).

Because the very same user control works fine if loaded in a full postback or dynamically added from a namespace works fine, I can be relatively sure that it only is trouble when loading via a partial page update into an UpdatePanel. I load the control via the LoadConrol method and then add it to the page via a PlaceHolder control. Theoretically, adding the User Control to the PlaceHolder should register itself and it's controls and events with the page, but it does not.

The following code sample is a UpdatePanel-free page using a user control that works, later I will show the same code with an UpdatePanel that does not.

I think I need to figure out how to register the controls and their events with the page without going through a full page postback. Any suggestions??

This example works as expected:
Default.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>23<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:PlaceHolder ID="UCPlaceHolder" runat="server"></asp:PlaceHolder>
12 </div>
13 </form>
14</body>
15</html>

Default.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
1011public partialclass _Default : System.Web.UI.Page
12{
13protected void Page_Load(object sender, EventArgs e)
14 {
15 Control ctl = LoadControl("~/UserControlDemo.ascx");
16 ctl.ID ="UC1";
17this.UCPlaceHolder.Controls.Add(ctl);
18 }
19}

UserControlDemo.ascx:
1<%@dotnet.itags.org. Control Language="C#" AutoEventWireup="true" CodeFile="UserControlDemo.ascx.cs" Inherits="UserControlDemo" %>2<asp:Button ID="Button1" runat="server" Text="Display from UC" OnClick="Button1_Click" /> <br />
3<br />
4<asp:Label ID="Content" runat="server" Text="Content"></asp:Label>

UserControlDemo.ascx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
1112public partialclass UserControlDemo : System.Web.UI.UserControl
13{
14protected void Page_Load(object sender, EventArgs e)
15 {
16 }
17protected void Button1_Click(object sender, EventArgs e)
18 {
19 Content.Text ="Content Changed.";
20 }
21}

Now, consider this variation, where instead of loading the control in the PageLoad event, you do so programmatically via a button Click event. This does not work as it cause a full postback which refreshes the placeholder. Viewstate does not seem to be working in this case. (uses the same user control as the previous example)

Default.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>23<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:Button ID="Button1" runat="server" Text="Load User Control" OnClick="Button1_Click" />
12 <br />
13 <br />
14 <asp:PlaceHolder ID="UCPlaceHolder" runat="server"></asp:PlaceHolder>
15 </div>
16 </form>
17</body>
18</html>

Default.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
1011public partialclass _Default : System.Web.UI.Page
12{
13protected void Page_Load(object sender, EventArgs e)
14 {
15 }
16protected void Button1_Click(object sender, EventArgs e)
17 {
18 Control ctl = LoadControl("~/UserControlDemo.ascx");
19 ctl.ID ="UC1";
20this.UCPlaceHolder.Controls.Add(ctl);
21 }
22}

To solve this postback problem, one would naturally want to use an UpdatePanel, like the following example. However this does not work as the controls do not seem to get registered with the page, and further nesting of user controls in UpdatePanels (to create a postback free app) are no better.

Default2.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>23<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
45<html xmlns="http://www.w3.org/1999/xhtml" >
6<head runat="server">
7 <title>Untitled Page</title>
8</head>
9<body>
10 <form id="form1" runat="server">
11 <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager>
12 <div>
13 <asp:UpdatePanel ID="UpdatePanel2" runat="server">
14 <ContentTemplate>
15 <asp:Button ID="Button1" runat="server" Text="Load User Control into UpdatePanel" OnClick="Button1_Click" />
16 </ContentTemplate>
17 </asp:UpdatePanel>
18 <br />
19 <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
20 <ContentTemplate>
21 <asp:PlaceHolder ID="ContentPlaceHolder" runat="server"></asp:PlaceHolder>
22 </ContentTemplate>
23 <Triggers>
24 <asp:AsyncPostBackTrigger ControlID="Button1" />
25 </Triggers>
26 </asp:UpdatePanel>
27 </div>
28 </form>
29</body>
30</html>

Default2.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
1112public partialclass Default2 : System.Web.UI.Page
13{
14protected void Page_Load(object sender, EventArgs e)
15 {
1617 }
18protected void Button1_Click(object sender, EventArgs e)
19 {
20 Control ctl = LoadControl("~/UserControlDemo.ascx");//loads into the page21 ctl.ID ="UC1";
22this.ContentPlaceHolder.Controls.Add(ctl);//adds to page control tree (or at least it should)23 }
24}

I know I can use the "visible" property of my controls to toggle them on and off a page to create a flicker free experience, however, my application is a database intensive app and I don't want the page running queries against the database unless I'm absolutely sure the user wants them. Rendering a 10 forms and keeping them hidden isn't a big deal, but running 10 queries that the user never wants to see is, otherwise I'd stick to that method, its works perfectly. Any suggestions? Or requests for clarification? Any help you can provide is much appreciated...thanks, Chris.

Chris, are you still working on this?

I've managed to get partial postbacks to fire events on the server from a button on a UserControl that was loaded as a result of a partial postback by an updatepanel.

Here's the code:

protected override void OnPreInit(EventArgs e){base.OnPreInit(e);if (this.Page.Request.Form["__UCTL"] !=null)this.ChangeControls(this.Page.Request.Form["__UCTL"].ToString(),null);elsethis.ChangeControls("Login","Login");}public void ChangeControls(String controlName, String controlTitle){ScriptManager.RegisterHiddenField(this,"__UCTL", controlName);this.host.ContentTemplateContainer.Controls.Clear();UserControl ctl = (UserControl)Page.LoadControl(CONTROL_DIRECTORY +"\\" + controlName +".ascx");ctl.ID = controlName;this.host.ContentTemplateContainer.Controls.Add(ctl);if (controlTitle !=null)this.host.Page.Title = controlTitle;}

I also created an Interface that has a method of ChangeControls with that signature and had my Page implement it so that my UserControls could get access to the method.


Hi Jason,

I figured out how to do it properly, you need to raise an event from the control and listen for it with the page or another control. The code to do so is also simpler than what you have. Check out this thread for more details: http://forums.asp.net/t/1123449.aspx

Feel free to msg me questions if you are confused.

-Chris

Programmatically adding ASP.net User Control to Partial Page Update / UpdatePanel

Hi All, I got a real doozy here. I have read hundreds upon hundreds offorum posts and found numerous others who have replicated this problem,but have yet to find a solution. Through testing I have been able tofind the cause of the problem, and will describe it here firsttextually and then through a code example.

Thepurpose of what I am trying to do is to create a postback-free webapplication through the use of ASP.net AJAX UpdatePanels and UserControls. When programmatically adding a User Control to a web pagethrough a normal postback everything works fine. All the controlswithin the user control are registered properly in the page and anyupdate panels included in the user control also work properly. HOWEVER,if instead of using a full postback you use an UpdatePanel and apartial page update of the UpdatePanel the controls do not getregistered with the page and events from them do not fire (forinstance, a button click event never hits the event breakpoint).

Becausethe very same user control works fine if loaded in a full postback ordynamically added from a namespace works fine, I can be relatively surethat it only is trouble when loading via a partial page update into anUpdatePanel. I load the control via the LoadConrol method and then addit to the page via a PlaceHolder control. Theoretically, adding theUser Control to the PlaceHolder should register itself and it'scontrols and events with the page, but it does not.

Thefollowing code sample is a UpdatePanel-free page using a user controlthat works, later I will show the same code with an UpdatePanel thatdoes not.

I think I need to figure out how to register thecontrols and their events with the page without going through a fullpage postback. Any suggestions??

This example works as expected:
Default.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:PlaceHolder ID="UCPlaceHolder" runat="server"></asp:PlaceHolder>
12 </div>
13 </form>
14</body>
15</html>

Default.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
10
11public partialclass _Default : System.Web.UI.Page
12{
13protected void Page_Load(object sender, EventArgs e)
14 {
15 Control ctl = LoadControl("~/UserControlDemo.ascx");
16 ctl.ID ="UC1";
17this.UCPlaceHolder.Controls.Add(ctl);
18 }
19}

UserControlDemo.ascx:
1<%@dotnet.itags.org. Control Language="C#" AutoEventWireup="true" CodeFile="UserControlDemo.ascx.cs" Inherits="UserControlDemo" %>
2<asp:Button ID="Button1" runat="server" Text="Display from UC" OnClick="Button1_Click" /> <br />
3<br />
4<asp:Label ID="Content" runat="server" Text="Content"></asp:Label>

UserControlDemo.ascx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11
12public partialclass UserControlDemo : System.Web.UI.UserControl
13{
14protected void Page_Load(object sender, EventArgs e)
15 {
16 }
17protected void Button1_Click(object sender, EventArgs e)
18 {
19 Content.Text ="Content Changed.";
20 }
21}

Now,consider this variation, where instead of loading the control in thePageLoad event, you do so programmatically via a button Click event.This does not work as it cause a full postback which refreshes theplaceholder. Viewstate does not seem to be working in this case. (usesthe same user control as the previous example)

Default.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:Button ID="Button1" runat="server" Text="Load User Control" OnClick="Button1_Click" />
12 <br />
13 <br />
14 <asp:PlaceHolder ID="UCPlaceHolder" runat="server"></asp:PlaceHolder>
15 </div>
16 </form>
17</body>
18</html>

Default.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
10
11public partialclass _Default : System.Web.UI.Page
12{
13protected void Page_Load(object sender, EventArgs e)
14 {
15 }
16protected void Button1_Click(object sender, EventArgs e)
17 {
18 Control ctl = LoadControl("~/UserControlDemo.ascx");
19 ctl.ID ="UC1";
20this.UCPlaceHolder.Controls.Add(ctl);
21 }
22}

Tosolve this postback problem, one would naturally want to use anUpdatePanel, like the following example. However this does not work asthe controls do not seem to get registered with the page, and furthernesting of user controls in UpdatePanels (to create a postback freeapp) are no better.

Default2.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5<html xmlns="http://www.w3.org/1999/xhtml" >
6<head runat="server">
7 <title>Untitled Page</title>
8</head>
9<body>
10 <form id="form1" runat="server">
11 <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager>
12 <div>
13 <asp:UpdatePanel ID="UpdatePanel2" runat="server">
14 <ContentTemplate>
15 <asp:Button ID="Button1" runat="server" Text="Load User Control into UpdatePanel" OnClick="Button1_Click" />
16 </ContentTemplate>
17 </asp:UpdatePanel>
18 <br />
19 <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
20 <ContentTemplate>
21 <asp:PlaceHolder ID="ContentPlaceHolder" runat="server"></asp:PlaceHolder>
22 </ContentTemplate>
23 <Triggers>
24 <asp:AsyncPostBackTrigger ControlID="Button1" />
25 </Triggers>
26 </asp:UpdatePanel>
27 </div>
28 </form>
29</body>
30</html>

Default2.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11
12public partialclass Default2 : System.Web.UI.Page
13{
14protected void Page_Load(object sender, EventArgs e)
15 {
16
17 }
18protected void Button1_Click(object sender, EventArgs e)
19 {
20 Control ctl = LoadControl("~/UserControlDemo.ascx");//loads into the page
21 ctl.ID ="UC1";
22this.ContentPlaceHolder.Controls.Add(ctl);//adds to page control tree (or at least it should)
23 }
24}

I knowI can use the "visible" property of my controls to toggle them on andoff a page to create a flicker free experience, however, my applicationis a database intensive app and I don't want the page running queriesagainst the database unless I'm absolutely sure the user wants them.Rendering a 10 forms and keeping them hidden isn't a big deal, butrunning 10 queries that the user never wants to see is, otherwise I'dstick to that method, its works perfectly. Any suggestions? Or requestsfor clarification? Any help you can provide is muchappreciated...thanks, Chris.

My suggestion is to not use an updatepanel for this. Google for ScottGu's blog on templating tricks; you can use a service to grab an ascx, feed it a datasource to populate the data then send the results to the page. use javascript to insert those results into the page DOM where needed, and code all your functionality in js or web methods of one form or another. It's a much cleaner / lower overhead way to do what you're trying to do anyway.


Hi Paul, I took a look at ScottGu blog, I believe this is the article you were referencing: http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for-non_2D00_UpdatePanel-scenarios.aspx

Unfortunately this is not the solution I am looking for. By using this method I lose the main benefits of ASP.net: managed code, event based triggers, and the rest of the integrated features. I believe this method will cause the same problem, whatever I load into the page, the page won't be aware of it and no events will fire.

For now I am going to have to use postbacks, and I'll used the update panels for keeping things like sorting gridviews postback-less.

Thanks for the suggestion though!


I am having exactly the same problem

Can someone please help?

In similar situations before, I have used javascript and other hacks, but I feel reluctant to try to do it again. If we have a framework that can be used and can make work simpler, then It makes sense.

However, these kind of problems are frustrating, and I don't know what is the resolution. I am sure people mus thave encountered this before.

Can someone help?


This is more a dynamic controls problem than an AJAX problem.

When you dynamically add a control, you have to add it EVERY request. By moving it from PageLoad to Button_Click, you've stopped creating the control every request. You only create it if the button is pressed. That is why the events won't fire when you use controls within the user control -- because on the postback, the control doesn't even exist! The postback data is for a control that isn't in the control tree, because you didn't add it, because the event that adds it isn't firing again.

The technique to solve this is to utilize viewstate to remember that the control has been added, so that you can add it from the LoadViewState method. In your click handler, call a new method - LoadUserControl(). Define LoadUserControl to create and add the control, and to set a viewstate key, ViewState["LoadUserControl"] = true. Then override LoadViewState, and after calling base.LoadViewState, look for that viewstate key. If its true, call LoadUserControl().

New problem... Now its possible it will be added twice -- if you click the same button a 2nd time, LoadViewState will call it, and so will your button click handler. So add code to your button click handler to avoid creating it if its already loaded -- just check for the viewstate key.


Infinities...This is very interesting, thank you for your response! Unfortunately you lose me when you talk about overriding the LoadViewState. How would you modify the following code to accomplish what you are saying?

protected void Button_Click(object sender, EventArgs e)
{
Control ctl = LoadControl("~/userControl.ascx");
this.Panel1.Controls.Add(ctl);
}
Thanks!

Ok, that sounds promising. But, I don't think the situation would work still.

I have a gridView. In every row of a gridview, one of the cells contains a nested update panel. When the user clicks on a particular row, a user control dynamically gets added to the nested update panel. This works fine.

When I click on a particular button INSIDE this user control then the postback disappears, no events are triggered and nothing happens. The fact that the control probably does not exist makes sense because it justifies what happens, as in no events are fired.

However now this user control has values and data inside it, so when you are saying to load that control again, what happens to the value and the data, it looks like that data is lost. Is that not right?

Basically, in my situation AJAX cannot help. In the first place my user control should already have a viewstate in order to persist the value of data and state of the elements inside the user control. Since its viewstate is not stored, the "re-adding" will simply not work at all.


gsinha25:

However now this user control has values and data inside it, so when you are saying to load that control again, what happens to the value and the data, it looks like that data is lost. Is that not right?

No that is not right. The fact you are loading it again doesn't mean its data is lost. All controls are reloaded every request, even the statically declared ones. ViewState maintains itself through the framework, but it only maintains the data in the control, not the control itself.

gsinha25:

Basically, in my situation AJAX cannot help.

You would have the same problem if you were not using ajax. What you'd see is that the loaded user control would disappear after you click a button in it.

gsinha25:

In the first place my user control should already have a viewstate in order to persist the value of data and state of the elements inside the user control. Since its viewstate is not stored, the "re-adding" will simply not work at all.

ViewState is maintained for the control. All you have to do is make sure it exists every request. It will work, trust me.


I'm sure the formatting of this is going to be off, but here's the basic idea.

protected void Button_Click(object sender, EventArgs e)
{
LoadUserControl();
}
private void LoadUserControl()
{
Control ctl = LoadControl("~/userControl.ascx");
this.Panel1.Controls.Clear();
this.Panel1.Controls.Add(ctl);

 ViewState["Loaded"] = true;

}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);

 if (ViewState["Loaded"] != null)
LoadUserControl();
 }


Hi Infinities,

This is starting to make sense. I believe what you are talking about will work for my problem - in fact I often assumed it had something to do with the viewstate, however my knowledge and experience with it is limited. (I am new to C# and ASP.net, coming over from ColdFusion.) I am still a little confused on the the LoadViewState override. As I understand it, this event fires after the Init event in the lifecyle, and it's goal is to reload the user control if it has been added to the page. One question that pops up here, and may be what gsinha was referencing, does chages to the control also progress if it is reloading the control every time? For instance, if the user control is a gridview populated from a database and I have sorted and/or filtered it, would these sorts and filters be passed along as well?

Another question, when you assign the view state key in "ViewState[" "] = true" does it matter which key you use? And a final question, where is the savedState object coming from in the LoadViewState override?

Thanks again for your help!

P.S. I read your writeup at your website on the viewstate, I think i'll need to read it three or four more times before I can make sense of it all but amazing stuff, I love the attention to detail!


ChrisCicc:

As I understand it, this event fires after the Init event in the lifecyle, and it's goal is to reload the user control if it has been added to the page.

The general role of LoadViewState is to deserialize the control's share of the page's entire viewstate payload. Think of viewstate as just a bunch of data -- data which is associated with each control on the page. On a postback, that data is available to the control that owns it again, if it's still around that is. The role of the code I gave you is to recreate the control if it was remembered previously that it had been created.

ChrisCicc:

One question that pops up here, and may be what gsinha was referencing, does chages to the control also progress if it is reloading the control every time? For instance, if the user control is a gridview populated from a database and I have sorted and/or filtered it, would these sorts and filters be passed along as well?

Yes -- because what you have to understand is that all controls are reloaded every request. In fact, the page is completely reconstructed from the ground up every request. Remember request/response mechanism of the web is essentially a stateless process. ASP.NET and other frameworks create the feeling of statefulness through tricks like ViewState and Session state. ViewState is persisted across posts -- the controls are not. You create the control tree for the page by either statically declaring it with asp.net markup, or by dynamically creating the controls yourself. But either way, the controls start completely fresh and new every request. ViewState is then deserialized and injected into the controls, restoring them to the state they were on the last request.

ChrisCicc:

Another question, when you assign the view state key in "ViewState[" "] = true" does it matter which key you use?

No -- the idea is just to remember the fact that the control was loaded. Each control's viewstate is scoped to it, so there's no risk of using a key thats already in use by some other control.

ChrisCicc:

And a final question, where is the savedState object coming from in the LoadViewState override?

That is the deserialized viewstate associated with that specific control. The base implementation uses it to repopulate the keys stored in the ViewState statebag.


ChrisCicc:

P.S. I read your writeup at your website on the viewstate, I think i'll need to read it three or four more times before I can make sense of it all but amazing stuff, I love the attention to detail!

Thanks for reading :) I know it's quite long... but hopefully worth it.


It works!! Thanks a bundle! This solved the most important problem I had, which was loading the user control on to the page via an Update Panel. It does however bring up a few further questions that I was hoping you could help with!

First, how do I modify your code so that I can have multiple buttons load different UCs each while still using the LoadViewState override? The following code is my best attempt at it:

Instead of using the click event to call the LoadUserControl function, I did this:

  
protected void LinkButton_Click(object sender, EventArgs e)
{
MainBodyPanel.Controls.Clear();
Control ctl = LoadControl("UserControl.ascx");
MainBodyPanel.Controls.Add(ctl);

ViewState["Loaded"] =true;
}

And then in the override I did as you suggested, only added an addtional If statement for each button and control,
and sent it back to the click event function instead of the LoadUserControl so that each control could have its
own viewstate key.
While I can add new controls to the page, I cannot see them again once another control calls the .clear()
function an all that is left is the viewstate which then throws an error as it doesn't see the same control tree.
Is there a better way?
 
The second problem I have is I cannot get different user controls to communicate with each other. This is
apparent in two places. The first is I have a user control with a set of links. it is these links that call the
other user controls into the update panel dynamically. If I add the UserControl dynamically before the page
loads, the links can't see the container panel on the page. I tried using this.findControl("...").Controls.Add()
but that didn't work. So for now I have the links hard coded into the page instead being their own user control,
but it's really too complex to keep doing it that way, and it limits my nesting options.
Thanks again for any help u can provide! 
 

Ok... help me understand :) You have a bunch of links, which when one is clicked, you want to dynamically load a user control into a particular spot. Is that 'spot' different for each link? If you click on one link and then another are there supposed to now be 2 controls on the page or does the 2nd one replace the first?

I'll assume you want only 1 control at a time.

What you described sounds like it should work. I personally wouldn't explicitly call the event handler -- thats usually a bad idea. It won't cause any problems if you know what you're doing but its better design to have a 3rd method that they both call, which gives each method a clear distinct purpose (its generally bad if you have to think... who called this method?).

One think you should definitely do is give the User Control you load a particular ID. Make the ID based on something that will (1) be exactly the same every time and (2) be different for different user controls. So for example, clicking on Link1 might load UC1.ascx with ID "uc1", and clicking Link2 might load UC2.ascx with ID "uc2". The reason for this is.. well, when you dont specify an ID, any control that requires one (textboxes for example) will use an autogenerated one. But if you load controls differently on a postback than you did on the first request, the IDs wont necessarily be the same, causing problems. Assigning an ID avoids that. You shouldn't have been getting the exception you mentioned... try what I said and let me know. If you still get it, show me some code...

About your user control communication problem... I'm not following 100%. Where and when exactly are you calling FindControl, and what control are you trying to find? With controls whenever you find yourself trying to get two of them to talk directly to each other... well its usually a sign that you could improve your design a bit. The control should be self sufficient, it shouldn't be broken because something else on the page isnt just so. Rather than have the control talk to the other control, you can have it raise an event. The page then listens for the event and decides what to do with it (something which the original control doesn't much care about), which may be to push something into another control on the page (the origin of which that control doesn't much care about). Much less coupled that way.


"I'll assume you want only 1 control at a time." correct assumption. there is a panel placeholder that the controls get swapped in and out of.

I tried adding the ID as you suggested but the exception still came up. Here is the code as it currently stands:

1protected void ViewCustomerListLinkButton_Click(object sender, EventArgs e)2 {3 MainBodyPanel.Controls.Clear();4 Control ctl = LoadControl("~/UserControls/CustomersControls/CustomerList.ascx");5 ctl.ID ="CustList";6 MainBodyPanel.Controls.Add(ctl);78 ViewState["CustList"] =true;9 }1011protected void AddCustomerLinkButton_Click(object sender, EventArgs e)12 {13 MainBodyPanel.Controls.Clear();14 Control ctl = LoadControl("~/UserControls/CustomersControls/CustomerAdd.ascx");15 ctl.ID ="CustAdd";16 MainBodyPanel.Controls.Add(ctl);1718 ViewState["CustAdd"] =true;19 }2021protected override void LoadViewState(object savedState)22 {23base.LoadViewState(savedState);2425if (ViewState["CustList"] !=null)26 ViewCustomerListLinkButton_Click(null,null);2728if (ViewState["CustAdd"] !=null)29 ViewCustomerListLinkButton_Click(null,null);3031 }

The exception is thrown because when I click on a second link, it Clears the MainBodyPanel control list, and the viewstate is looking for the control list that includes the now removed control. I tried various ways I could think of to remove the viewstate but to no avail...

"What you described sounds like it should work. I personally wouldn'texplicitly call the event handler -- thats usually a bad idea. It won'tcause any problems if you know what you're doing but its better designto have a 3rd method that they both call, which gives each method aclear distinct purpose (its generally bad if you have to think... whocalled this method?)."

I couldn't figure out a way to do this. I was having each click event pass the url via the function call LoadUserControl("~/control.ascx") but I couldn't figure out how to have the loadviewstate override pass the url back when needed, so I did it as you see above.

About the communication problem, in more detail, the problem is actually with the code above. Right now that is in my pages code behind, if i make those links into a user control, and then add the control to the page with those functions in the controls code behind, it cannot see the container panel (which in this case is the MainBodyPanel). I tried using the find control method but it still couldn't see it. With the links and event handlers hard coded it works fine.

Thanks!


With this code, once you click on one of the buttons, that control will always be loaded. When you click on one button you need to 'clear' the viewstate key of the other, otherwise you'll be trying to load both controls all the time. Pretty sure that is why you are getting the error, too. Easier if you just use the same key with a different value.

About the event handler thing...

protected void Link1_Handler(object sender, EventArgs args) { Foo(); }
private void Foo() { /* load Foo, set ViewState["Loaded"] = 1 */ };

protected void Link2_Handler(object sender, EventArgs args) { Bar(); }
private void Bar() { /* load Bar, set ViewState["Loaded"] = 2 */ };

protected override void LoadViewState(object savedState) {
base.LoadViewState(savedState);

if(ViewState["Loaded"] == 1) {
Foo();
}
else if(ViewState["Loaded"] == 2) {
Bar();
}
}

You might be tempted to store the path to the actual UserControl in ViewState, that way you can just LoadControl(ViewState["Loaded"]) ... but, don't :) Treat ViewState like user input. Don't trust it. If you did it that way, the user could maniuplate viewstate in such a way that they could cause any user control in your site to load, rather than be restricted to the two you want.

Ok... so I'm still confused about your links problem. You have each link as a user control, and when clicked you want them to load their content into the parent? Controls should not modify their parent's controls. It would be better like I said, to have an event raised by the control. The page, which contains all these link controls, just hooks that event on each control and then loads the control into the appropriate place. Your FindControl probably isn't working because FindControl only finds controls within the current naming container. User controls are naming containers. So when you say, this.FindControl("foo") from within a UserControl, you're only looking for a control named "foo" WITHIN the user control, not higher. To go higher you have to call FindControl on a control thats higher. But you still have to be careful with naming containers. You could start at the page level with this.Page.FindControl("foo"), but that will only find controls named "foo" that are children of page or children of non-naming containers in page. Imagine if you had a user control that contained control with ID "foo", and then you put 5 of them on the page. Which would you expect Page.FindControl("foo") to find? Its ambiguous -- thats why it won't find ANY. Each Foo is within a naming container, so their actual IDs are "uc1$foo", "uc2$foo", etc (where uc1=id of user control 1). If you know for sure the control will be in a particular place (for you it sounds like in a master page), then go ahead and hard code that ID... but be warned, its a fragile way to do it. Another approach is to have your Page expose a "MasterContainer" property of type Control. The user controls can then just say ((MyPageType)this.Page).MasterContainer.Controls.Add(), and it will work so long as the control is on a page that inherits from "MyPage" (which, all of your pages could inherit from).Ad infinitum... lots of different ways to deal with it.

programmatically created buttons click event handler not working in updatepanel

i have a hovermenuextender with Target Control - an updatepanel, PopupControl - a panel with button named edit.

when i press edit, a textbox, and a button are created programmatically and placed inside the updatepanel.

the button's click event has a handler (added programmatically) which shud replace the text in updatepanel with the text in textbox, but this is not working - here's the snippet:

1protected void OrseButton_Click(object sender, EventArgs e)2 {3 OrseUpdatePanel.ContentTemplateContainer.Controls.Add(tbox);4 OrseUpdatePanel.ContentTemplateContainer.Controls.Add(savebtn);5 savebtn.Text ="Save";6 savebtn.Click +=new EventHandler(savebtn_Click);7 }89void savebtn_Click(object sender, EventArgs e)10 {11string temp;12 temp = tbox.Text;13 OrseUpdatePanel.ContentTemplateContainer.Controls.Clear();14 OrseUpdatePanel.ContentTemplateContainer.Controls.Add(new LiteralControl(temp));1516//throw new Exception("The method or operation is not implemented.");17 }

help me on this...i m using vs 2005, asp with ajax, c#

whats hapening is ur manipulating ur button and events at runtime, so when the page postback, the buton info and event is lost, what u need to to is save the whole thing to a viewstate, then on page call back u must recall this viewstate and reassign it to the button.

savebtn.Text ="Save";
savebtn.Click +=new EventHandler(savebtn_Click);

ViewsState["btn"] = savebtn;

On ur callback

savebtn = (button)ViewsState["btn"]

Hope this helps


i placed :

savebtn = (button)ViewsState["btn"]

in savebtn_click method.

now when i run it, it gives error serializing value 'system.web.ui.webcontrols.button' of type 'system.web.ui.webcontrols.button'


ok, on each callback recreate the event for ur button, coz when creating event at runtime, and when there'sa postback or callback, the event is lost, so have to recreate it and Once created ASP.Net directly rebind it.


can i have some example code...i wanna make sure i got u completely.

Programmatically created Submit button on UpdatePanel want fire without The UpdatePanel be

I have programmatically created some controls(labels, buttons) that make up and object in several rows of a table on an UpdatePanel. On the initial load of the page, I create all the objects(controls). Then I click one of the buttons to do a partialrendering update of some the controls in the UpdatePanel. The button click causes a post back which I throught was good. The problem is that if i do not refesh the entire set of controls on the UpdatePanel first, the button click want fire and I can't firgure out why.

Here is some of the code:

<asp:ScriptManagerID="ScriptManager1"runat="server"EnablePartialRendering="true"AsyncPostBackTimeout="36000"/><asp:UpdatePanelID="UpdatePanel2"runat="server"ChildrenAsTriggers="false"UpdateMode="Conditional"><ContentTemplate><asp:TableID="Table1"runat="server"></asp:Table><asp:UpdateProgressID="UpdateProgress"runat="server"AssociatedUpdatePanelID="UpdatePanel2"><ProgressTemplate>

Processing Service Request .........

</ProgressTemplate></asp:UpdateProgress></ContentTemplate></asp:UpdatePanel>

protectedvoid btnSubmit_Click(object sender,EventArgs e)

{

RefreshStatus(); --> Causes controls to be built on UpdatePanel.

}

protectedvoid Page_Load(object sender,EventArgs e)

}

if (!IsPostBack)

{

}

else

{

<-- If I do a"RefreshStatus();"here, all works fine but the entire set of controls on the UpdatePane is re-Built. Not what I want.

}

Button Click:

void ChangeStatus_Click(object sender,EventArgs e)

{

Button ChangeStatus = (Button)sender;

----- Update subset of controls on UpdatePanel here -------

}

Since there is no ReFreshStatus() during the postback the button wantfire and nothing happens. I am puzzel by this.

Any Ideas?

Thanks

I forgot mention the each button is built with a AsyncPostBack trigger, ie:

// Add Updatepanel Triggers for the buttonAsyncPostBackTrigger trigForBtns;

trigForBtns =

newAsyncPostBackTrigger();

trigForBtns.ControlID = ChangeStatus.ID;

trigForBtns.EventName =

"Click";

Thanks again, I really need some help with this.


I just wanted to mention that I solved this problem byImplementing Ajax incremental asynochronous updating of controls on the web page.


Thats niceSmile

Can you post some code details here ?

Programmatically creating UpdatePanel and creating Triggers

I'm connecting to a database to get a number then using a for loop to create multiple sets of controls. I'm generating a textbox (which happens to use an AutoCompleteExtender) then adding an EventHandler for that text box which updates a RadioButtonList by connecting to a database. I'm rendering the RadioButtonList in a new UpdatePanel control. Then I'm using the .RegisterAsyncPostBackControl() method for my scriptmanager to get async postback for the new update panel.

The only way I could get the EventHandler to fire is if I manually set .AutoPostBack = true for the TextBox. I'm assuming this is why the whole page posts back instead of just the UpdatePanel.

I'm completely new to these Ajax tools. I'd like to figure out a way to make only the contents of the update panel (the RadioButtonList) to update instead of the entire page. Here's some of my code:

protectedvoid Page_Load(object sender,EventArgs e)

{

// Code to connect to the database to get a value for numCoupons...

for (i = 0; i < numCoupons; i++)

{

Panel pnl =newPanel();pnl.ID ="pnl_" + i;

defaultCoupons_pnl.Controls.Add(pnl);

TextBox couponTitle =newTextBox();

couponTitle.ID ="couponTitle_" + i;

pnl.Controls.Add(couponTitle);

couponTitle.AutoPostBack =true;

couponTitle.TextChanged +=newEventHandler(couponTitle_TextChanged);

AjaxControlToolkit.AutoCompleteExtender CouponSearch =new AjaxControlToolkit.AutoCompleteExtender();CouponSearch.ID ="cpnAutoComplete_" + i;

CouponSearch.TargetControlID = couponTitle.ID;

CouponSearch.ServicePath ="AutoComplete.asmx";

CouponSearch.ServiceMethod ="GetCompletionList";

pnl.Controls.Add(CouponSearch);

UpdatePanel descriptionChoices =newUpdatePanel();descriptionChoices.ID ="couponChoices_" + i;

pnl.Controls.Add(descriptionChoices);

ScriptManager1.RegisterAsyncPostBackControl(couponTitle);

RadioButtonList descriptionList =newRadioButtonList();descriptionList.ID ="couponList_" + i;

descriptionChoices.ContentTemplateContainer.Controls.Add(descriptionList);

}a

}

protectedvoid couponTitle_TextChanged(object sender,EventArgs e)

{

// Code to connect to database and query results based on couponTitle entry...

string searchTerm = ((TextBox)sender).Text;findCoupon_objCmd.Parameters.Add(new SqlParameter("@dotnet.itags.org.searchTerm", searchTerm));

findCoupon_objConn.Open();

string couponNumber = ((TextBox)sender).ID.ToString().Replace("couponTitle_","");

SqlDataReader DR = findCoupon_objCmd.ExecuteReader();

RadioButtonList descriptionChoices = (RadioButtonList)defaultCoupons_pnl.FindControl("pnl_" + couponNumber).FindControl("couponChoices_" + couponNumber).FindControl("couponList_" + couponNumber);

descriptionChoices.DataSource = DR;

descriptionChoices.DataTextField ="description";

descriptionChoices.DataValueField ="allowedCouponId";

descriptionChoices.DataBind();

findCoupon_objConn.Close();

}

Hi,

You can seeCreating updatepanels at runtime? andIs it possible to add a ScriptManager and/or UpdatePanel to a MasterPage from a ContentPage dynaically? to find out how to Programmatically creating UpdatePanel.

Also seehttp://www.asp.net/ajax/documentation/live/overview/UpdatePanelOverview.aspx for the following section:

To add anUpdatePanel control to a page programmatically, you create a new instance of theUpdatePanel control. You then add controls to it by using theContentTemplateContainer property and theAdd(Control) method. Do not add controls directly to theContentTemplate property.

When anUpdatePanel control is added programmatically, only postbacks from controls in the same naming container as theUpdatePanel control can be used as triggers for the panel.

The following example shows how to programmatically add anUpdatePanel control to a page. The example adds aLabel and aButton control to the update panel by using theContentTemplateContainer property. Because theChildrenAsTriggers property istrue by default, theButton control acts as a trigger for the panel.

You cann't create Triggers Programmatically:

You can add anUpdatePanel control programmatically, but you cannot add triggers programmatically. To create trigger-like behavior, you can register a control on the page as an asynchronous postback control. You do this by calling theRegisterAsyncPostBackControl(Control) method of theScriptManager control. You can then create an event handler that runs in response to the asynchronous postback, and in the handler, call theUpdate() method of theUpdatePanel control.

Best Regards,

Monday, March 26, 2012

Programmatically setting EnablePartialRendering to false from master page

Hi,

I have a master page which has its content area wrapped inside an updatepanel. To facilitate debugging, I'ld like to "disable" the updatepanel when the request URL contains ?debug=true.

I understood that to disable the updatepanel, setting EnablePartialRendering to false should do the trick. This can only be done from PreInit.

The problem I'm facing now is that:

The master page doesn't have an OnPreInit method to overrideWhen I override the OnPreInit in the content page, there's no ScriptManager available (via ScriptManager.GetCurrent(Page)), since the ScriptManager is defined in the master page.

Any idea on how I can solve this without having to create 2 master pages (with & without the UpdatePanel) and dynamically switching between both?

Wouter

Locate the WebpartManger in masterpage by

this.MasterPage.FindControl("yourwebpartmangerid");


Thanks for the hint. I was able to locate the scriptmanager in this way and disable the partial rendering.

However, a new problem arose after I did all this. The page showed two assert popup boxes:

"Assertion Failed: Could not resolve reference to object named "_PageRequestManager" for "dataContext" property on object of type "Sys.Binding""

"Assertion Failed: No data context available for binding with ID "" and dataPath "inPostBack" on object of type "Sys.UI.Control""

I've tracked this down to the UpdateProgress control, which still renders xml-script while EnablePartialRendering is false (see also http://forums.asp.net/thread/1250774.aspx)

I'm now trying to programmatically remove or disable the UpgradeProgress control as well, but had no luck so far :(


hello.

ah, i remember that...well, in fact, the class has 2 bugs:

1. the 1st is that it renders xml-script without checking for its visible property
2. the 2nd is that the interface is implemented explicitly without any delegation to a protected virtual method (this would let you easilly fix this).

so, your best option is to write your own updateprogress control.

Progress template not showing

I got an updatepanle, an updateprogress , a label inside the update panel, and a button outside the updatepanel, what i wanna do is just simple, delay 5 sec before showing the label and at the same time showing the "loading..." before it complete. Problem occured when i put the button outiside of the updatepanel and it did not show the "loading.." and after 5 sec the label will shown , but everything works fine when i put the button in the updatepanel...I did set the button as trigger.

so may i know where is the problem ?

Thanx~

Hi giox,

Posting the code of your page would help us in locating the eventual problem.

Would you be so kind to use the Source Code button of the rich editor to insert code? TNX!

Kind regards,
Wim


i dont believe you need to set the button as a trigger if its in the update panel, also, have you tried setting the update progress "DisplayAfter" property to "0"?


Wim,

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="lbl1" runat="server" Style="left: 48px; top: 0px" Text="Label" Width="352px"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" />
</Triggers>
</asp:UpdatePanel>
</div>

<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="0">
<ProgressTemplate>
loading..
</ProgressTemplate>
</asp:UpdateProgress>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
</form>

VB code :

Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
System.Threading.Thread.Sleep(3000)
Me.lbl1.Text = "abc"
End Sub

Thanx~


Lee Brennan:

i dont believe you need to set the button as a trigger if its in the update panel, also, have you tried setting the update progress "DisplayAfter" property to "0"?

The problem occured when the button is outside the update panel..

I tried to set "DisplayAfter" property to "0", but it still not working. thanx anyway.


The documentation is the problem on this one. If you look at the AssocitatedUpdatePanelID attribute, it states "You can set theAssociatedUpdatePanelID property to controls in the same naming container, a parent naming container, or the page."

What exactly that means is certainly not clear, because it does not work if it is used as a sibling of the UpdatePanel. (and you would think that that's what "in the same naming container" means)

If you delete the AssociatedUpdatePanelID completely, your example will work.

Of if you move the UpdateProgress "as is" inside the UpdatePanel, it will also work.


If want to show the UpdateProgress for a control which is outside the UpdatePanel you have to manually hook the initializeRequest and endRequest of PageRequestManager to show the UpdateProgress, like the following:

<script type="text/javascript"> var prm = Sys.WebForms.PageRequestManager.getInstance(); prm.add_initializeRequest(initializeRequest); prm.add_endRequest(endRequest); var _postBackElement; function initializeRequest(sender, e) { if (prm.get_isInAsyncPostBack()) { e.set_cancel(true); } _postBackElement = e.get_postBackElement(); if (_postBackElement.id.indexOf('Button1') > -1) { $get('UpdateProgress1').style.display = 'block'; } } function endRequest(sender, e) { if (_postBackElement.id.indexOf('Button1') > -1) { $get('UpdateProgress1').style.display = 'none'; } }</script>

While I use the technique above as well for most projects, it is not necessary in this example. Simply eliminating the AssociatedUpdatePanelID attribute on the ProgressPanel will allow the example to work. That occurs because Button1 is also defined as a trigger for the panel. What was confusing is why it doesn't work with the attribute set because that is not clear from the documentation for the AssociatedUpdatePanelID attribute.

When reading the documentation for the UpdateProgress, none the scenarios described include the way the example was initially written. Only when the attribute is deleted does the following statement (bold type) apply:

"If you do not set theAssociatedUpdatePanelID property, theUpdateProgress control displays progress for any asynchronous postback that originates from inside anyUpdatePanelor for controls that are triggers for panels."


wrayx1:

While I use the technique above as well for most projects, it is not necessary in this example. Simply eliminating the AssociatedUpdatePanelID attribute on the ProgressPanel will allow the example to work. That occurs because Button1 is also defined as a trigger for the panel. What was confusing is why it doesn't work with the attribute set because that is not clear from the documentation for the AssociatedUpdatePanelID attribute.

It works when eliminating the AssociatedUpdatePanelID ...Thanx..the problem has solved, thanx to those who helping to solve this problem as well.

Progressbar while the updatePanel is updating or the controls are rendering in the UpdateP

Hi Guyz,

Can anybody please tell me, how can i display a progressbar on the page with Ajax, which will stay there till the time data in the Updatepanel is loading. I have a gridview in a updatepanel which displays data from the database, it has paging enabled now what i want is when user changes the page. There should be a progressbar which says Loading ... or some message like that.

I have read some posts about UpdateProgress i think its not there in Ajax Beta 1 or 2. But there is UpdatePanelAnimationExtender.
But could not find anything useful. Is there any examples for this.

Can anybody please help.

Thanks
Amit

hi amit,

did u watched scott's video i hope it will help you. open this url in media playerhttp://download.microsoft.com/download/7/8/f/78f2d61a-74c6-47b6-835c-0d1efa5524af/ScuttGu_asp_net_atlas.wmv

or onhttp://ajax.asp.net see

Video - Developing ASP.NET 2.0 Applications using AJAX

by Scott Guthrie, General Manager, .NET Development Platform

at bottom of home page.

thanks,

satish.


Thanks satish

But its really easy with the help of updateprogress control. you can put the text you want to display while the updatepanel is updating. and that's it.

It will work for you.

Anyways thanks for your help again.

Amit


no worries amit. though lucky u working on AJAX its really wonderful but its not coming my way in my companySad.

regards,

satish.


i am just using prebuilt components, not doing my own programming with ajax.
It's really easy to use man. not a big deal.

Amit

Proper time to add UpdatePanel trigger

What is the proper time to add a trigger to an UpdatePanel from code-behind?

I currently have a control that acts as a NamingContainer. I am trying to have it register a couple of its buttons as async triggers if it senses that it is a child of an UpdatePanel. This is because these controls are databound (there are multiples of them in one UpdatePanel) so I cannot add the IDs of the controls declaratively.

I tried adding them in the PreRender phase of the control, but when I try it out I get a nasty exception on Render during a postback (below). I can only assume (from reflection) that initially, the triggers are being created when the controls are recreated from ViewState, then the controls those triggers reference get tossed aside when the list databinds after the change, so there's a null reference when the triggers from the first set try to find their real controls. However, I don't have any idea how to avoid this. Any help would be greatly appreciated.

Object reference not set to an instance of an object. 0.273490066474929 0.000559
at System.Web.UI.AsyncPostBackTrigger.HasTriggered()
at System.Web.UI.UpdatePanelTriggerCollection.HasTriggered()
at System.Web.UI.UpdatePanel.get_RequiresUpdate()
at System.Web.UI.PageRequestManager.ProcessUpdatePanels()
at System.Web.UI.PageRequestManager.RenderPageCallback(HtmlTextWriter writer, Control pageControl)
at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
at System.Web.UI.Page.Render(HtmlTextWriter writer)
at IDM.Manage.UI.Page.Render(HtmlTextWriter writer) in C:\Projects\IDM.Manage\IDM.Manage\UI\Page.cs:line 39

I had this same problem when trying to add a trigger in the Page_Load.

It worked fine when I moved it to the Page_Init

Saturday, March 24, 2012

put an AutoPostBack=true control inside a updatepanel?

Hi, All:

Just upgrade to AJAX. Everything works greate. Maybe this is a simple question.

I have a gridview which is inside in a updatepanel. then I have an dropdownlist inside a ItemTemplate of my GridView and this the autopostback attribute of this ddl is set to true. I have a onselectedindexchanged event to do something and refresh the gridview (old fashion way). Does this autopostback= true will refresh the whole page ( I have other controls on this page except theis gridview). I tried and It looks like it just refresh the gridview only. Am I right? If I set the autopostback=false, then nothing happened. I can not put this ddl into Triggers since it is an control in the itemtemplate of the gridview

Another question, with this ddl index changed event, I want to change partial of the gridview only, say show or hide a label in another itemtemplate, what should I do? put the updatepanel inside the itemtemplate??

Thanks

-rockdale

Hello rockdale,

Question: *** I tried and It looks like it just refresh the gridview only. Am I right? ***
YES, since it's inside the UpdatePanel. Leave your AutoPostBack=True.

Question: *** I want to change partial of the gridview only, say show or hide a label in another itemtemplate ***
Step1: *** onselectedindexchanged event to do something and refresh the gridview (old fashion way). ***

Sample:
<asp:gridview id="gridview1"... >
<columns>
<asp:templatefield>
<itemtemplate>
<asp:Label id="lblName" Text="John Smith" runat="server" />
</itemtemplate>
...

At Step1, you can hide or show part of your gridview.

dim ctrl as control
ctrl = controlfinder.fincontrol(me.gridview1, "lblName")
if not ctrl is nothing then
ctype(ctrl, label).visible = true or false
end if

WS


Question about DropDownList behavior inside an UpdatePanel

Hi,

I have an application that has two DropDownLists on a page. The first is just a plain ASP DropDownList; the second is an ASP DropDownList inside an UpdatePanel. The page also contains a label inside a second UpdatePanel.

When the item in the first DropDownList is changed, the second DropDownList is populated. When the item in the second DropDownList is changed, the Label's text is changed.

I have noticed that when the first DropDownList changes, the second DropDownList "flickers" as it populates. When I select a value in the second list, the label updates as it should, but the second DropDownList again flickers, as if it is also being refreshed. Both UpdatePanels have UpdateMode="conditional" set.

My question is whether this is normal behavior on the second DropDownList, since it is inside an UpdatePanel, or do I have something set wrong? It's a minor issue, but kind of annoying since I would not expect to see any kind of refresh when changing a value in the second DropDownList.

I have included a simple example which shows what I'm talking about. Thanks as always for your help!

<%@dotnet.itags.org.PageLanguage="vb"AutoEventWireup="false"CodeBehind="Default.aspx.vb"Inherits="DropDownTest._Default" %>

<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<htmlxmlns="http://www.w3.org/1999/xhtml">

<headrunat="server">

<title>Untitled Page</title>

</head>

<body>

<formid="form1"runat="server">

<asp:ScriptManagerID="ScriptManager1"runat="server"/>

<div>

<ASP:DROPDOWNLISTid="DropDownList1"autopostback="true"runat="server"width="110px"></ASP:DROPDOWNLIST>

<br/><br/><br/><br/><br/><br/>

<ASP:UPDATEPANELid="UpdatePanel1"runat="server"updatemode="conditional">

<CONTENTTEMPLATE>

<ASP:DROPDOWNLISTid="DropDownList2"autopostback="true"runat="server"width="110px"></ASP:DROPDOWNLIST>

</CONTENTTEMPLATE>

<TRIGGERS>

<ASP:ASYNCPOSTBACKTRIGGERcontrolid="DropDownList1"eventname="SelectedIndexChanged"/>

</TRIGGERS>

</ASP:UPDATEPANEL>

<br/><br/><br/><br/><br/><br/>

<ASP:UPDATEPANELid="UpdatePanel2"runat="server"updatemode="conditional">

<CONTENTTEMPLATE>

<ASP:LABELid="Label1"runat="server"text="Label"></ASP:LABEL>

</CONTENTTEMPLATE>

<TRIGGERS>

<ASP:ASYNCPOSTBACKTRIGGERcontrolid="DropDownList2"eventname="SelectedIndexChanged"/>

</TRIGGERS>

</ASP:UPDATEPANEL>

</div>

</form>

</body>

</html>

PartialPublicClass _Default

Inherits System.Web.UI.Page

ProtectedSub Page_Load(ByVal senderAsObject,ByVal eAs System.EventArgs)HandlesMe.Load

IfNot IsPostBackThen

Me.DropDownList1.Items.Clear()

Dim objListItemAs ListItem

objListItem =New ListItem

objListItem.Text = 1

Me.DropDownList1.Items.Add(objListItem)objListItem =New ListItem

objListItem.Text = 2

Me.DropDownList1.Items.Add(objListItem)

objListItem =New ListItem

objListItem.Text = 3

Me.DropDownList1.Items.Add(objListItem)

EndIf

EndSub

PrivateSub DropDownList1_SelectedIndexChanged(ByVal senderAsObject,ByVal eAs System.EventArgs)Handles DropDownList1.SelectedIndexChanged

Me.DropDownList2.Items.Clear()

Dim objListItemAs ListItemobjListItem =New ListItem

objListItem.Text = 9

Me.DropDownList2.Items.Add(objListItem)

objListItem =New ListItem

objListItem.Text = 8

Me.DropDownList2.Items.Add(objListItem)objListItem =New ListItem

objListItem.Text = 7

Me.DropDownList2.Items.Add(objListItem)

EndSub

PrivateSub DropDownList2_SelectedIndexChanged(ByVal senderAsObject,ByVal eAs System.EventArgs)Handles DropDownList2.SelectedIndexChanged

Me.Label1.Text =Me.DropDownList1.SelectedValue +Me.DropDownList2.SelectedValue

EndSub

EndClass

Does this happen in both FF and IE6/7?


Definitely in IE6, as that's my default right now. I tried Firefox, and it does not seem to have this issue.

I also noticed that in IE6, when I select the item in the first list, the item is highlighted (dark blue background) until I move focus. When I select an item in the second list, the highlighting is removed. This could simply be because the focus shifted to the label. Neither list stays highlighted in Firefox.

So, it appears that it may be an IE quirk. Has anyone else seen this issue or found a work around? I should be getting IE7 on my PC in the next week or two, so maybe that will solve it!


IE6 blows. I know - Shocking news!

Try it out on IE7 and see if that fixes your problem.

I realize that some of the world is still using IE6, some can't even upgrade to 7 (ie. Win2K users) but I hate coding for that browser.


You should set the property of the UpdatePanel named "UpdatePanel2":updatemode="all"

Question about the ScriptManagerProxy

I have a question about the ScriptManagerProxy control.

I have a .master page that uses an UpdatePanel with a ScriptManager and I want the child pages of this MasterPage to be able to use an UpdatePanel control also. I can't have another ScriptManager control on the child pages so how do I use the ScriptManagerProxy control to point to the ScriptManager on the MasterPage? Is this possible?

Thanks

Hi,

the ScriptManagerProxy is used to add references to script files and web services, but nothing prevents you to use an UpdatePanel in a child page, if you have the ScriptManager on the master page.


Oh okay. So I don't even need a ScriptManagerProxy control. I can just use the ScriptManager that I have in the .master page. I'll try it out and then let you know how it goes...Thanks!

I did what you said (pretty simple and easy, I was making it too complex) and it worked great! But, I didn't/don't have enough knowledge about the UpdatePanel that this was not exactly what I wanted it to do. I'll try to explain it as best as I can.

On my .master page I have a menu with several hyperlinks. All of these hyperlinks point to the same page (links.aspx which is a child page of the .master page) However, these hyperlinks carry with them a QueryString of data that will very depending upon which hyperlink the user clicked on. What I want to happen is this: When a user clicks on a hyperlink on the menu it will just update that part of the site with the new data that is brought in in accord with the QueryString and does not refresh the entire page. I think it might have something to do with the triggers in the UpdatePanel. Does this make any sense?

Thanks,

Wednesday, March 21, 2012

question about timer

Hi there,

I made a ajax tabcontainer with updatepanel and timer. the timer is running for change activetabindex every 30 seconds.

Now i want to reset timer when user click tab from their explorer. otherwises if the timer running at 25 seconds and user click to another tab, they want to write down something, they only got 5 seconds to do that.

any idea i can do that?

thanks

You can use theOnClientActiveTabChanged event of the TabContainer to stop or reset your Timer when the tabs are changed manually.

Also, you might consider handling those tab changes on the client side, instead of using the Timer. Since all of the tabs are rendered and tab changes are just client side events, it's fairly inefficient to force partial postbacks every 30 seconds just to change the tab. You can use setInterval or setTimeout to achieve the same result, without requiring postbacks.


Hi gt1329a,

thanks replying my post. i will try onclientactivetabchanged event. but for your client side events i am not quite get your point.

could you pls give me some code example for client side event? thanks

best regards,

martin


Hi,

Do it like this:

<ajaxToolkit:TabContainer ID="TabContainer1" runat="server"OnClientActiveTabChanged="resetTimer()">

functionresetTimer(){
var b = $find(<%= Timer1.ClientID %>);
if(b){
b._stopTimer();
b._startTimer();
}
}

Best Regards,

Question about updatepanel

Hi,
I got a problem about update panel.
My scenario is that:
I have two tasks, each of which is triggered by buttons..
"A" needs 10 seconds to complete, and "B" needs 2 seconds.
After clicking A button, the user click B within 10 seconds.
Normally the program will stop doing A and start doing B, right?
But once I use the UpdatePanel, it just keep doing A and doesn't do B.
WHY?

Here is my example code:

<body> <form id="form1" runat="server"> <atlas:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True"/> <asp:Button ID="ButtonA" runat="server" Text="intensive task" /> <asp:Button ID="ButtonB" runat="server" Text="interrupt task" />  <asp:Label ID="Label2" runat="server" /> <atlas:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" /l> </ContentTemplate> <Triggers> <atlas:ControlEventTrigger ControlID="ButtonA" EventName="Click" /> </Triggers> </atlas:UpdatePanel> <atlas:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> Processing... </ProgressTemplate> </atlas:UpdateProgress> </form> </body>
Protected Sub ButtonA_Click(ByVal senderAs Object,ByVal eAs System.EventArgs)Handles ButtonA.Click System.Threading.Thread.Sleep(10000) Label1.Text ="Intensive task suceeded!!"End Sub Protected Sub ButtonB_Click(ByVal senderAs Object,ByVal eAs System.EventArgs)Handles ButtonB.Click Label2.Text ="Interrupted task succeeded!!"End Sub
I need the normal function, that is to stop A and do B when clicking ButtonB, and also the function of partial refreshing. Any ideas?Could anyone give me some suggestion?

Question about UpdatePanel

Hi !

I have a user control with an objectDataSource and a dropDownList. These controls are inside a user control because they will be reused in some pages.

This user control has a property that returns the selectedValue of the combo.

So, in one page I add the usercontrol, another objectdatasource and a gridview. The property in the first user control is a parameter for the 2nd objectDataSource.

So, I would like to eliminate the postback when I change the 1st combo. I tried to put the 2nd ObjectDataSource and the gridview inside an UpdatePanel and create a Triger linking with the user control property, but it fails, the gridview doesn't appears.

I tried some other combinations to, and nothing works.

So : how to use a web user control to trigger an UpdatePanel ?

The UpdatePanel identifies some properties of the controls, just some. Why ? What can I do to get my property in user control recognized by UpdatePanel triggers ?

Thanks!

P.S. : Sorry by my English, I don't speak English well.

[]'s

Dennes

Hi Dennes,

Although Visual Studio doesn't show custom properties on UserControls (it's a technical limitation in VS2005), you should be able to type it in manually in source view. At runtime it should all just work.

Thanks,

Eilon


Hi !

I already tried this, but doesn't work. I think It's because I'm using a web user control, trying to make a trigger point to a custom property in web user control. I think I need to do something more, but don't know exactly what.

Just pointing the trigger to the property doesn't work.

[]'s

Dennes


Hi Dennes, can you show me a sample that reproduces this problem?

Thanks,

Eilon


Hi, Eilon !

Here, the user control :

PartialClass usrComboInherits System.Web.UI.UserControlPublic ReadOnly Property Categoria()As Integer Get If ddlCategorias.SelectedValue <>""Then Return (ddlCategorias.SelectedValue)Else Return (Nothing)End If End Get End PropertyEnd Class

<%@. Control Language="VB" AutoEventWireup="false" CodeFile="usrCombo.ascx.vb" Inherits="usrCombo" %><asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString%>" SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]"></asp:SqlDataSource><asp:DropDownList ID="ddlCategorias" runat="server" AutoPostBack="True" DataSourceID="SqlDataSource1" DataTextField="CategoryName" DataValueField="CategoryID"></asp:DropDownList>

The page, default.aspx :

<%@. Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %><%@. Register src="http://pics.10026.com/?src=usrCombo.ascx" TagName="usrCombo" TagPrefix="uc1" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <atlas:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True" /> <uc1:usrCombo ID="UsrCombo1" runat="server" /> <br /> <atlas:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString%>" SelectCommand="SELECT [ProductID], [ProductName], [UnitPrice], [UnitsInStock] FROM [Products] WHERE ([CategoryID] = @.CategoryID)"> <SelectParameters> <asp:ControlParameter ControlID="UsrCombo1" Name="CategoryID" PropertyName="Categoria" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" BackColor="LightGoldenrodYellow" BorderColor="Tan" BorderWidth="1px" CellPadding="2" DataKeyNames="ProductID" DataSourceID="SqlDataSource1" ForeColor="Black" GridLines="None"> <FooterStyle BackColor="Tan" /> <Columns> <asp:BoundField DataField="ProductID" HeaderText="ProductID" InsertVisible="False" ReadOnly="True" SortExpression="ProductID" /> <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" /> <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" SortExpression="UnitPrice" /> <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" SortExpression="UnitsInStock" /> </Columns> <SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" /> <PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" /> <HeaderStyle BackColor="Tan" Font-Bold="True" /> <AlternatingRowStyle BackColor="PaleGoldenrod" /> </asp:GridView> </ContentTemplate> <Triggers> <atlas:ControlValueTrigger ControlID="UsrCombo1" PropertyName="Categoria" /> </Triggers> </atlas:UpdatePanel> <br />   </form></body></html>

In this case, the postback still happens, the trigger is ignored. This same sample with a dropdownlist instead the user control works fine, the user control is the problem

So, I tried again, with the combo inside the UpdatePanel and no triggers. I get surprised, because it worked, but in my website It doesn't.

So, I couldn't reproduce the complete problem, just one part. My webpage is more complicated, it uses objectDataSource, call webservices and uses a customParameter (ReflectionParameter), uses a masterPage with other user controls in other parts of the complete page. One of these caused the problem with atlas, I'm still trying to discover.

My last try resulted in the following message :

Error : 'Sys.Application.findObject(...)' is null or not an object

[]'s

Dennes

Question about UpdatePanel Triggers in a MasterPage

Hello,

I have a MasterPage defining the structural layout of my site with a left menu and content areas. In the content area I have an UpdatePanel that needs to update its controls when a button in the menu area is clicked. The button is outside the UpdatePanel so I tried specifying an AsyncPostBackTrigger but I got the following exception: A control with ID 'BtnNavigate' could not be found for the trigger in UpdatePanel 'PnlUpdate'. It seems that the button must be in the same naming container as the UpdatePanel for this to work.

I found a workaround for this problem by moving the real button in the same container as the UpdatePanel and hiding it with display: none. Then I put a dummy button in the menu area which just invokes the click event of the real button with some javascript. This works fine in IE but in Firefox a total PostBack is done when I click the button in the menu area.

Here's the code of a simple page that illustrates this behavior:

<%@dotnet.itags.org. Page Language="C#" MasterPageFile="~/Web/MasterPage.master" Title="Untitled Page" %><script runat="server"> protected void RealButton_Click(object sender, EventArgs e) { LblTest.Text = DateTime.Now.ToLongTimeString(); }</script><asp:Content ID="LeftNav" ContentPlaceHolderID="LeftNav" Runat="Server"> <input type="button" onclick="$get('<%= RealButton.ClientID %>').click();" value="Test" /></asp:Content><asp:Content ID="Content" ContentPlaceHolderID="Content" Runat="Server"> <ajax:ScriptManager ID="ScriptManager" runat="server" /> <ajax:UpdatePanel ID="up1" runat="server"> <ContentTemplate> <asp:Label ID="LblTest" runat="server" /> </ContentTemplate> <Triggers> <ajax:AsyncPostBackTrigger ControlID="RealButton" /> </Triggers> </ajax:UpdatePanel> <asp:Button ID="RealButton" runat="server" style="display: none;" OnClick="RealButton_Click" /> </asp:Content>

Any suggestions that could help me resolving this issue are welcome. Thanks for your time.


PS. I forgot to mention that I am using Ajax RC1.

Ok, I think I figured it out:

Using

<asp:Button ID="RealButton" runat="server" style="display: none;" OnClick="RealButton_Click" UseSubmitBehavior="false" />
instead of
<asp:Button ID="RealButton" runat="server" style="display: none;" OnClick="RealButton_Click" />
replaces the total PostBack in Firefox with an AsyncPostBack.

OK I've come up with a work around that I think is a bit nicer than the dummy button thing.

I've created a custom control called EventProxy in my project that has a public event EventProxied and a public method ProxyEvent(EventArgs e). For each control or User control event on your page that you want to use as an async postback trigger on an update panel in a different ConntentPlaceHolder, add an instance of EventProxy to the same ContentPlaceHolder the update panel is in and use that instance's EventProxied event as the async event. Then in the handler code for the control/user control event's on the page, call the appropriate EventProxy control's ProxyEvent() method. Example code:

EventProxy Control:

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;

namespace PlanIt.Web.Controls

{

publicclassEventProxy :Control,IPostBackEventHandler

{

public EventProxy()

{ }

publicvoid RaisePostBackEvent(string eventArgument)

{ }

publiceventEventHandler<EventArgs> EventProxied;

protectedvirtualvoid OnEventProxy(EventArgs e)

{

if (this.EventProxied !=null)

{

this.EventProxied(this, e);

}

}

publicvoid ProxyEvent(EventArgs e)

{

OnEventProxy(e);

}

}

}

Page Markup:

<%@.PageLanguage="C#"MasterPageFile="~/PlanItMaster.Master"Theme="Standard"AutoEventWireup="true"CodeBehind="EventProxyExample.aspx.cs"Inherits="PlanIt.Web.EventProxyExample"%>

<%@.RegisterAssembly="PlanIt.Web"Namespace="PlanIt.Web.Controls"TagPrefix="PlanIt"%>

<%@.RegisterSrc="~/Controls/TripTitle.ascx"TagName="TripTitleControl"TagPrefix="PlanIt"%>

<%@.RegisterSrc="~/Controls/BudgetControl.ascx"TagName="BudgetControl"TagPrefix="PlanIt"%>

<asp:ContentID="Content1"ContentPlaceHolderID="cphLeftPane"runat="server">

<asp:UpdatePanelID="updTitle"runat="server"UpdateMode="Conditional"ChildrenAsTriggers="true">

<ContentTemplate>

<PlanIt:TripTitleControlID="planItTripTitle"runat="server"OnTripTitleChanged="planItTripTitle_TripTitleChanged"/>

</ContentTemplate>

</asp:UpdatePanel>

</asp:Content>

<asp:ContentID="Content2"ContentPlaceHolderID="cphRightPane"runat="server">

<asp:UpdatePanelID="updBudget"runat="server"UpdateMode="Conditional"ChildrenAsTriggers="true">

<ContentTemplate>

<PlanIt:BudgetControlID="planItBudgetControl"runat="server"/>

</ContentTemplate>

<Triggers>

<asp:AsyncPostBackTriggerControlID="epTripTitleChanged"EventName="EventProxied"/>

</Triggers>

</asp:UpdatePanel>

<PlanIt:EventProxyID="epTripTitleChanged"runat="server"/>

</asp:Content>

Page Code Behind:

using System;

using System.Data;

using System.Configuration;

using System.Collections;

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;

namespace PlanIt.Web

{

publicpartialclassEventProxyExample : System.Web.UI.Page

{

protectedvoid Page_Load(object sender,EventArgs e)

{ }

protectedvoid planItTripTitle_TripTitleChanged(object sender, TripTitleChangedEventArgs e)

{

epTripTitleChanged.ProxyEvent(e);

// force a refresh of the budget control

planItBudgetControl.Refresh();

}

}

}

Cheers,

D.