Editing the rendering of web controls without inheriting from them

I have written on several occasions on the issue of editing the rendering of ASPX webpages and controls, in order to edit it as we wish without having to haves access to the source code.

On this occasion I’m going to comment on a quite unknown control feature that enables us to modify its rendering results directly, without having to inherit from them (the usual technique) nor other complicated techniques. What we’ll do is make the most of a method from the System.Web.UI.Control class supposedly intended only for internal use, but which Microsoft has left as public and therefore accessible directly to anyone.

It is the SetRenderMethodDelegate method. This enables us to assign a delegate to the RenderMethod type function which substitutes the control rendering method in question. The assigned method takes two parameters: a HtmlTextWriter that we’ll use to generate the rendering of the control and a reference to the control whose method we are going to replace.

Let’s see it in a very simple example. Create a new webpage and add it a label, a text box, a button and another label below, this way:

When clicking the button we’ll show in the second Label a “Hello” plus the name entered in the text box, this way:

    protected void Button1_Click(object sender, EventArgs e)
    {
        Label2.Text = "Hello " + TextBox1.Text;
    }

It’s impossible to do it simpler :-)

Ok. Now we are going to edit the HTML which renders the second label, so that, if there is something written in the text box, it ignores the Label2 rendering by default (that would display “Hello” followed by the text entered in the text box), and place some other thing.

What we’ll do is create a custom rendering method which adheres to the RenderControl delegate definition:

    protected void CustomRenderForLabel(HtmlTextWriter output, Control container)
    {
        if (TextBox1.Text != "")
            output.Write("<b>Here</b> I put whatever I want " + TextBox1.Text);

    }

Now, in the Load event of the page we assign this method as render method for the control:

    protected void Page_Load(object sender, EventArgs e)
    {
        this.Label2.SetRenderMethodDelegate(this.CustomRenderForLabel);
    }

If we now execute the page we’ll see that, in place of the assigned text in the button click event, what we have is a phrase such as: “Here I put whatever I want, Joe”, with the first word in bold letters.

Obviously this example is foolish, performed to simply show how to do this. This technique is aimed to edit the rendering of control in a specific page in which the HTML that it generates by default doesn’t fit our needs.

Another important limitation of this technique to consider is that we cannot obtain the default rendering of a control and then edit it (there are other techniques for this). We have to generate directly all the new HTML for the control we are intercepting. Obviously we cannot call the control render method in order to get its default HTML, since what this does is calling again our render method which has substituted the original one, entering an infinite loop (try placing container.Render() inside your rendering method and you’ll see).

Another important question that we have to keep in mind is that this technique won’t work with all the controls, since it depends on how the methods are implemented internally. As long as the control render method calls the System.Web.UI.Control base control render method it will work. If it omits this call (it’s not mandatory), then it won’t work. Label calls the base method, but most controls don’t do so.

Then, what is it good for besides labels (which is quite irrelevant)? Well, for example, the page class inherits from Control and you can also use this technique with it.

In addition, there are simple controls that form part of more complex controls and that can be edited this way. For example, the controls that represent the cells of a table in a grid. An interesting example, of this is editing the header of a  GridView, making it render in a different way and adding, for instance, extra grouping headers.

In general we can use this technique with controls in which we focus on their source code and use directly the render method of the System.Web.UI.Control class base, which are quite a few, and most are container controls of others or very simple controls.

This technique is the one used by ASP.NET’s infrastructure to evaluate code blocks in the markup of the page of the <%= %> and <%: %> type (not so for binding expressions <%# %> that work differently at run-time). If we go to ASP.NET’s temporary directory and examine the source code generated automatically for any page we can see it more clearly.

JM Alarcon

ASP.NET/IIS MVP

ASP.NET/IIS MVP since 2004. MsC Mechanical engineering and business consultant specialist, he has written several books and hundreds of articles on computer science and engineering in specialized press such as PC World, Windows Magazine, dotNetMania....

, ,

No comments yet.

Leave a Reply