In my last post I was waxing on about the problems with <%= %> markup in pages and content containers and the inability to use Control.Controls.Add() to add controls dynamically at runtime. If you do this you get a nasty error message that 'The Control Collection cannot be modified because the control contains code blocks'.
To put this in context, what I'm trying to do is to dynamically generate binding error messages as controls are unbound from databinding, and then display them without requiring to put validators on the page first. The idea is you add a DataBinder to the page, and the DataBinder extends any control on the page. You set binding properties a few possible validation settings (IsRequired) and then call DataBind() to bind the form controls, UnBind()to bind the data from the control back into the binding source. Any errors that occur, are picked up and dumped into a BindingError Collection. The errors also trigger the insertion of binding error messages on the controls. At the moment Controls.Add() is used which has the reliability problem mentioned above.
It works great – as long as there are no script <%= %> markup tags on the page or content container. I mentioned yesterday some workarounds to make this work by using <%# %> Databinding expressions or wrapping the script code/tags into a separate server container tag like <div runat="server"> which effectively removes the script from the parsing container.
All that's all fine and good, but I want this to be a generic solution so these workarounds are not quite cutting it.
So, I started looking for some other solutions. I figured there would be some way to override the rendering of the control or rather hook the rendering and then inject markup afterwards. It looked like Control.SetRenderMethodDelegate() would work to hook the control's rendering, but as it turns out SetRenderMethodDelegate() is applied only to Container controls, and only fires for the control's inner content. It doesn't fire on typical controls like TextBox and even if it did it wouldn't do me any good to override the content rendering. I want to hook the 'outer' rendering so I can inject markup before or after the Control's Render() method fires.
So, there's no way to hook the rendering of a control, from outside of the control itself. This seems to be a pretty big omission in ASP.NET. The combination of the <% %> markup behavior of Control.Controls.Add() and the lack of some hook that allows hooking into the Rendering of a control externally seems really limiting. It makes it difficult to reliably build extender controls that might need to expand on the functionality of existing controls, which is exactly what I'm doing here.
So, question: Does anybody see a way to do what I'm trying to do, reliably beyond the hacky workarounds I've described here? Anybody know of a way to create pre or post markup for a control externally (ie. without overriding the control class itself)?
Other Posts you might also like