开发者

Add additional content into a known content placeholder from a user control

I have a UserControl that has some javascript I'd like to inject into a known ContentPlaceHolder.

I was hoping to do something like the following except when I append to add the control to found control I get an exception which says I cannot modify the control collection in the Init, Load or PreRender events:

"UserControl.ascx"


 <%@ Control Language="C#" %>
 <asp:Checkbox runat="server" id="checkBox"/>
 <app:JavascriptInjector runat="server" InjectInto="ScriptPlaceHolder">
      $(function(){ $('#<%= checkBox.ClientID %>').click(function() { ... });
 </script></app:JavascriptInjector>

"JavascriptInjector.cs"

using System;
using System.Diagnostics;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;

public class JavascriptInjector : PlaceHolder
{
    public string InjectInto
    {
        get { return this.ViewState["InjectInto"] as string; }
        set { this.ViewState["InjectInto"] = value; }
    }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        this.PreRender += this.__PreRender;
    }

    private void __PreRender(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(this.InjectInto))
        {
            goto performRegularlly;
        }

        var injectInto = this.FindControlRecursively(this.Page);

        if (injectInto == null)
        {
            goto p开发者_StackOverflow中文版erformRegularlly;
        }

        injectInto.Controls.Add(this);

        return;

        performRegularlly:

        Debug.WriteLine("performing regularlly");
    }

    private Control FindControlRecursively(Control current)
    {
        var found = current.FindControl(this.InjectInto);

        if (found != null)
        {
            return found;
        }

        foreach (var child in current.Controls.Cast<Control>())
        {
            return this.FindControlRecursively(child);
        }

        return null;
    }
}


I figured it out. The following JavascriptInjector class will work, although I don't know what the implications are of calling the render method in the PreRender. Also think I may need to do something to figure out which type of HtmlTextWriter that the base application is using.

"JavaScriptInjector.cs"

using System;
using System.IO;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;

public class JavascriptInjector : PlaceHolder
{
    private bool performRegularlly;

    public string InjectInto
    {
        get { return this.ViewState["InjectInto"] as string; }
        set { this.ViewState["InjectInto"] = value; }
    }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        this.PreRender += this.__PreRender;
    }

    protected override void Render(HtmlTextWriter writer)
    {
        if (this.performRegularlly)
        {
            base.Render(writer);
        }
    }

    private void __PreRender(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(this.InjectInto))
        {
            goto performRegularlly;
        }

        var injectInto = this.FindControlRecursively(this.Page);

        if (injectInto == null)
        {
            goto performRegularlly;
        }

        performRegularlly = false;

        using (var stringWriter = new StringWriter())
        using (var writer = new HtmlTextWriter(stringWriter))
        {
            base.Render(writer);

            writer.Flush();

            injectInto.Controls.Add(new LiteralControl(stringWriter.GetStringBuilder().ToString()));
        }

        this.Controls.Clear();

        return;

        performRegularlly: this.performRegularlly = true;
    }

    private Control FindControlRecursively(Control current)
    {
        var found = current.FindControl(this.InjectInto);

        if (found != null)
        {
            return found;
        }

        foreach (var child in current.Controls.Cast<Control>())
        {
            return this.FindControlRecursively(child);
        }

        return null;
    }
}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜