PNG Fix Component
Needing a solution to fix transparent PNG in IE6 I came to start using one of the many javascript based solutions to do this. But when it came time to use ajax and populating new images in my postbacks this obviously broke. So I created a custom ASP.NET Component to help me do this...
Control:
I created a custom
ASP.NET Ajax server Component to do this, the code is
below:
namespace PNGFix {
public class PNGFix : ScriptControl {
#region Properties
private string m_FixImage =
"/stefansedich/png-fix-control/images/dotClear.gif";
public string FixImage {
get {
return m_FixImage;
}
set
{
m_FixImage = value;
}
}
private bool NeedsPNGFix
{
get {
HttpContext
ctx = HttpContext.Current;
return
(ctx.Request.ServerVariables["HTTP_User_Agent"].IndexOf("MSIE")
> -1)
&&
(ctx.Request.Browser.Version == "6.0");
}
}
#endregion
#region Script Descriptors
protected override IEnumerable<ScriptDescriptor>
GetScriptDescriptors() {
ScriptComponentDescriptor descriptor = null;
if (this.NeedsPNGFix) {
// Only add
script descriptors if we need to fix png i.e. IE 5.5 or
6...
descriptor = new
ScriptComponentDescriptor("PNGFix.PNGFix");
descriptor.AddProperty("FixImage", this.FixImage);
}
yield return descriptor;
}
// Generate the script reference
protected override IEnumerable<ScriptReference>
GetScriptReferences() {
ScriptReference
reference = null;
if
(this.NeedsPNGFix) {
reference = new
ScriptReference("PNGFix.PNGFix.js",
this.GetType().Assembly.FullName);
}
yield return reference;
}
#endregion
#region Custom Rendering
public override void RenderBeginTag(HtmlTextWriter writer) {
}
public override void
RenderEndTag(HtmlTextWriter writer) { }
protected override void RenderContents(HtmlTextWriter
writer) {
if (this.NeedsPNGFix) {
writer.Write(@"<style type='text/css'>img, input.image
{ visibility:hidden; } </style>");
}
}
#endregion
}
}
The fix image property is the location
of the 1x1 transparent gif used. I use the NeedsPNGFix
property to only output the component if we are in a browser
that needs it. ATM I am only checking for IE and version 6.0
which worked in my test case. All this control does if if
needed outputs the styles needed to let this work in IE6 and
setups up the script.
Client Script:
Type.registerNamespace("PNGFix");
PNGFix.PNGFix
= function() {
this.onRequestEnd = null;
this.mFixImage = "";
PNGFix.PNGFix.initializeBase(this);
}
PNGFix.PNGFix.prototype = {
initialize: function() {
PNGFix.PNGFix.callBaseMethod(this, 'initialize');
// Attach event handlers so that when an async
request finshes
// we fix all pngs again...
this.onRequestEnd = Function.createCallback(this.requestEnd,
{Me: this});
// Attach to the
request end event.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(this.onRequestEnd);
// Run PNGFix code
this.fixPNG();
},
dispose: function() {
PNGFix.PNGFix.callBaseMethod(this, 'dispose');
},
get_FixImage: function() {
return this.mFixImage;
},
set_FixImage :
function(value) {
this.mFixImage = value;
},
requestEnd: function(sender, args, state) {
// At the end of a request call the FIXPNG
function again.
state.Me.fixPNG();
},
fixPNG: function() {
// CODE HERE TO FIX PNG IN IE6...
}
}
PNGFix.PNGFix.registerClass('PNGFix.PNGFix',
Sys.Component);
if (typeof(Sys) !== 'undefined')
Sys.Application.notifyScriptLoaded();
Explination:
I have not supplied the code I used to fix the PNG as I am
yet to email the author to get permission to distribute, so
when that is done will post full source code or redo the PNG
fix myself. In here we register to the endRequest of the
PageRequestManager this will fire whenever an async postback
occurs. In here we run the PNGFix script again to fix any
new pngs we might have added through postback. We also fire
the FixPNG method the first time the page loads to fix any
png images on the page.
Usage:
To use the control simply at the top of your page add the
control:
<cc1:PNGFix ID="PNGFix1" runat="server"
FixImage="/stefansedich/png-fix-control/images/dotClear.gif"
/>
And presto you will now have transparent
PNG support in IE6 with ASP.NET AJAX.
This is obviously not finished and
could have bugs but in my small test it worked fine. I will
enhance this and release the source code to anyone
interested ASAP...
Thanks
Stefan