Search code examples
asp.nettelerikcustom-server-controls

How to put a 3rd party server control inside a custom server control in ASP.Net?


I am using Telerik ASP.Net Ajax controls (theoretically shouldn't matter who makes the 3rd party control). I would like to create my own custom server control (not user control) that has my own predefined HTML output but also includes a Telerik DatePicker. Since the Telerik DatePicker is another server control what is the correct procedure to place a server control into my custom server control.

My understanding is that server controls work by writing html output. How can I write the output of another control that I instantiate in the Render method and still retain the original controls individual lifecycle.

Desired outcome:

  • My own custom server control that contains many 3rd party controls (ie. RadDatePicker).

Solution

Thanks to @Sumo for pointing me into the direction of the Composite control. Documentation is available here.

I was able to solve the issue by creating a control that inherits CompositeDataBoundControl. Then databinding my datasource, calculating how many custom controls needed, placing them into an ArrayList and instantiating them correctly (with their own lifecycle in CreateChildControls()). I was then able to render each control in the ArrayList of DatePicker in the Render() method by invoking the ArrayList index that has not been rendered yet. Eg. ((RadDatePicker)datePickerArray(instantiatedDatePickersCount)).RenderControl(writer).

Its a dirty solution at the moment but It works for my testing purposes.


Solution

  • You'll want to create a CompositeControl. This allows you to easily add HTML markup and controls using an override of CreateChildControls and not have to think about too much else.

    Some sample code:

    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    
    namespace TestServerControls {
        [DefaultProperty("Text")]
        [ToolboxData("<{0}:GridWithHeader runat=server></{0}:GridWithHeader>")]
        public class GridWithHeader : CompositeControl {
            private readonly GridView _grid = new GridView();
            private readonly HtmlGenericControl _header = new HtmlGenericControl("h1");
    
            public string Text {
                get { return _header.InnerHtml; }
                set { _header.InnerHtml = value; }
            }
    
            protected override void CreateChildControls() {
                Controls.Add(_header);
                Controls.Add(_grid);
            }
        }
    }