Can I automatically attach to the lifecycle of ANY server-enabled HTML tag?
If a "server-enabled" HTML tag is in a Web form, like this --
<p runat="server"/>
-- 开发者_如何学Pythonis there any way for me to attach to its rendering? I assume once they have runat="server", they must have a lifecycle of some kind.
I'd like to attach some code to the rendering of any HTML tag so enabled. So, whenever a template author puts runat="server" on a tag, I can catch the PreRender (or anything else) and execute some code.
Possible?
This is something done using adapters. You create one that does its magic, and associated it in a browser file contained in App_Browsers.
Here's an example of my experimental App_Browsers/Default.browser
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlControl"
adapterType="App_Code.Adapters.HtmlControlAdapter" />
</controlAdapters>
</browser>
</browsers>
And my adapter...
using System.Web.UI; using System.Web.UI.Adapters;
using System.Web.UI;
using System.Web.UI.Adapters;
namespace App_Code.Adapters {
public class HtmlControlAdapter : ControlAdapter {
protected override void Render(HtmlTextWriter writer) {
writer.Write("<div style='background-color: #f00;'>");
base.Render(writer);
writer.Write("</div>");
}
}
}
My highly advanced adapter with superfragilicious abilities renders a div with inline styles around all controls deriving from HtmlControl (html-tags with runat="server", including <form runat="server">). Your adapter can hook into any event triggered by the control, so this should solve your needs.
Here is a link to the page lifecycle article. It's an important piece of information to know.
If you are coding it then you could create a class and override PreRender doing whatever you want inside it. Then your controls would implement that class.
If you prefer a more generic approach then you could do the same thing but at the page level. You could hook OnPreRender at the page level as such:
private void Page_PreRender(object sender, System.EventArgs e)
{
Page page = sender as Page;
if (page != null)
{
page.Controls.Clear(); // Or do whatever u want with ur page...
}
}
private void InitializeComponent()
{
// Handle the Page.PreRender event.
this.PreRender += new System.EventHandler(this.Page_PreRender);
}
That should give you the ability to check each control just before rendering.
I think this is what I'm looking for. It recursively iterates the entire control tree, and binds the event handler when it finds a HtmlControl.
protected override void OnLoad(System.EventArgs e)
{
base.OnLoad(e);
BindTagProcessor(Page);
}
private void BindTagProcessor(Control control)
{
foreach (Control childControl in control.Controls)
{
if (childControl is HtmlControl)
{
((HtmlControl)childControl).PreRender += new EventHandler(MyTagProcessor);
}
BindTagProcessor(childControl);
}
}
精彩评论