Tuesday, January 1, 2008

UpdatePanel Css StyleSheet upon partial-refresh bug in IE

The update panel seems to have a bug when registering an external stylesheet or including css styles from within the contents that will be getting partially rendered. The bug only seems to occur in IE, works nicely in firefox. Impressive indeed. My problems started when i had a control that needed to render a link to an external stylesheet, which was quite mm easy and normal.

I mean i've been there and done that plenty of times, however this time there were situations in which the stylesheet needed to be registered if my control was included in an updatepanel and kept invisible during inital load, while enabling it only upon a partial postback. TRICKY TRICKY TRICKY!

More over, there is an old bug opened and closed with a reason "this is by design". Seems awkward to me that this is by design and only effects IE :-(
The url to the bug report is here :


I resolved by registering the css in the OnInit phase of my custom control. Since this would run and register the css even if the control was disabled or invisible, which is what i was after, since it registered the control with the page on first load instead of trying to rendering the style link as part of my rendering for the control(which obviously didn't work in IE). A simplied piece of my code of how i have worked around this problem is as follows :
protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
ScriptManager sm = ScriptManager.GetCurrent(Page);
    if (!sm.IsInAsyncPostBack)
{
       string css = string.Format("<link rel=\"stylesheet\" 
        href=\"{0}\" type=\"text/css\" />", 
ResolveUrl(CssClassFile));

ScriptManager.RegisterClientScriptBlock(this, 
      typeof(MyBlahControl), "MyBlahId", css, false);
}
}

Update 01/01/2008 : Please read the first two comments below. CSS contianment from within the <body element violates xhtml specs and as such here is an update that includes the css in the <head section. Thanks to Ram Krisna for pointing out/commenting this.
protected override void OnInit(EventArgs e)
{
  base.OnInit(e);
ScriptManager sm = ScriptManager.GetCurrent(Page);
  if (!sm.IsInAsyncPostBack)
{
HtmlLink l = new HtmlLink();
l.Href = ResolveUrl(CssClassFile);
l.Attributes.Add("rel", "stylesheet");
l.Attributes.Add("type", "text/css");
Page.Header.Controls.Add(l);
}
}

A simplified test of what I feel is an open bug and should be fixed can be seen below. After clicking the button, the style applied to the label is lost and happens only in IE7, donno about previous versions since i have not tested :
<%@ Page Language="C#" %>

<script runat="server">

protected void Button1_Click(object sender, EventArgs e)
{
// do something
}

</script>

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

<html xmlns="http://www.w3.org/1999/xhtml">
<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>
<!-- 
Note below that for simplicity i am not
using an external stylesheet. Anyway, even with an external style
sheet the result is the same. The style is 
not applied after partial postback 
-->
<style type="text/css">
.MakeGreen{background-color:green;}
</style>
<asp:Label ID="Label1" CssClass="MakeGreen" 
runat="server" Text="Label"></asp:Label>

<asp:Button ID="Button1" runat="server" Text="Partial refresh"
OnClick="Button1_Click" />

</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>

7 comments:

  1. I am try to do that but getting an error like script tag not proper outside the script

    ReplyDelete
  2. I encountered a similar issue recently with embedded Styles within an UpdatePanel. I cross posted from my blog:

    http://rrfreeman.blogspot.com/2010/01/ie-bug-embedded-css-styles-within.html

    ReplyDelete
  3. My problem is this: I have an ASP.NET application that has ajax forms w/ validations, and everything works fine locally. When I deploy to SharePoint 2007 (which is the production environment), the validations do not show up after the first ajax call has been made on the page. Is this the same issue described here? Every other bit of css in my external stylesheet works just fine... The only problem is the css for the validations remains at display:none (even though the validations still fire correctly). Could someone help point me in the direction to fix this issue? Thank you.

    ReplyDelete
  4. This works for me thank you

    ReplyDelete
  5. Thanks for this wonderful technique. I was really struggling this issue during asynchronous postback and all my embededded images were not showing up in IE. Great work thanks...

    ReplyDelete
  6. This fix works a treat. A lot of time had been lost over this and a lot more would have been without this post. Thanks for the detail and example test.

    ReplyDelete
  7. can't get it working... may I ask what is "CssClassFile"?

    ReplyDelete