Добавить дополнительный контент в известный заполнитель контента из пользовательского элемента управления - PullRequest
2 голосов
/ 26 августа 2010

У меня есть UserControl, в котором есть какой-то javascript, который я хотел бы вставить в известный ContentPlaceHolder.

Я надеялся сделать что-то вроде следующего, кроме случаев, когда я добавляю элемент управления в найденный элемент управления и получаю исключение, которое говорит, что я не могу изменить коллекцию элементов управления в событиях Init, Load или PreRender:

"UserControl.ascx"

<code>
 <%@ 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 Ответ

2 голосов
/ 26 августа 2010

Я понял это. Следующий класс JavascriptInjector будет работать, хотя я не знаю, каков будет вызов метода render в PreRender. Также подумайте, что мне, возможно, нужно что-то сделать, чтобы выяснить, какой тип 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;
    }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...