从用户控件将其他内容添加到已知内容占位符中

时间:2010-08-26 13:46:30

标签: asp.net user-controls

我有一个UserControl有一些javascript,我想注入一个已知的ContentPlaceHolder

我希望做以下的事情,除非我追加将控件添加到找到的控件时我得到一个异常,说我无法在Init,Load或PreRender事件中修改控件集合:

“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 performRegularlly;
        }

        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;
    }
}

1 个答案:

答案 0 :(得分:2)

我明白了。以下JavascriptInjector类将起作用,但我不知道在PreRender中调用render方法有什么影响。另外我想我可能需要做些什么来弄清楚基础应用程序正在使用哪种类型的HtmlTextWriter

“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;
    }
}