Showing posts with label area. Show all posts
Showing posts with label area. Show all posts

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.

Wednesday, March 21, 2012

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.