我有一个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;
}
}
答案 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;
}
}