开发者

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

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜