Search code examples
asp.netwebformswebusercontrol

Single Reference to CSS File from ASCX Control


I'm writing an ASCX control that needs to reference both a JavaScript file and a CSS file.

Obviously, I only want the host page to reference these files once. So I'm using Page.ClientScript.RegisterClientScriptInclude() to reference the JavaScript file. The CSS file, however, is a bit more complicated.

I thought maybe I could do the following:

if (!Page.ClientScript.IsClientScriptIncludeRegistered(ScriptManagerJsKey))
{
    Page.ClientScript.RegisterClientScriptInclude(this.GetType(), ScriptManagerJsKey, ResolveClientUrl("~/javascript/PaymentSchedule.js"));

    HtmlLink cssLink = new HtmlLink();
    cssLink.Href = "~/css/PaymentSchedule.css";
    cssLink.Attributes["rel"] = "stylesheet";
    cssLink.Attributes["type"] = "text/css";
    Page.Header.Controls.Add(cssLink);
}

The idea here was to add an HtmlLink to reference the CSS file in the page header, but only once. Since I believe this code will only add the JavaScript reference once, I thought this would do the trick.

However, this actually adds the reference to the CSS file twice in the head section of the file.

Has anyone found a trick to referencing a CSS file only once from an ASCX control?


Solution

  • I'm not sure why my original code shouldn't work. It seems like IsClientScriptIncludeRegistered() should prevent the code within my if statement from running more than once.

    At any rate, here's how I worked around it:

    private static readonly string ScriptManagerJsKey = "PaymentScheduleControls.ascx.js";
    private static readonly string CssLinkId = "PaymentScheduleControlCssLink";
    
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.ClientScript.IsClientScriptIncludeRegistered(ScriptManagerJsKey))
        {
            Page.ClientScript.RegisterClientScriptInclude(this.GetType(), ScriptManagerJsKey, ResolveClientUrl("~/javascript/PaymentSchedule.js"));
            if (Page.Header.FindControl(CssLinkId) == null)
            {
                HtmlLink cssLink = new HtmlLink();
                cssLink.ID = CssLinkId;
                cssLink.Href = "~/css/PaymentSchedule.css";
                cssLink.Attributes["rel"] = "stylesheet";
                cssLink.Attributes["type"] = "text/css";
                Page.Header.Controls.Add(cssLink);
            }
        }
    }
    

    This code simply sets an explicit ID for the CSS link control. It then takes steps to only add the link if it isn't already added. Seems to work okay.