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 = "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="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
 

6 Comments

Comments have been disabled for this content.