Music. Coding. Gaming. Life.

Extending ASP.Net Controls with Child Controls

Posted Monday, April 9th, 2007 8:07:00 pm
If you've ever tried to extend an ASP.Net control that has child controls in a custom control sitting in your App_Code directory, then you know the frustration of the lack of Intellisense for those child controls. When you try to enter the correct control that should go inside your child control, you get an error saying "Element 'TableRow' is not a known element. This can occur if there is a compilation error in the Web site.

Of course, when you compile and view the page in your browser, everything is okay. What is making Visual Studio find these seemingly phantom errors?

The reason is because you are using different assemblies. When ASP.Net compiles your custom control in the App_Code directory, it puts it in its own assembly. This assembly, of course, is different from the assembly the child controls are in. Since you have not defined any child controls in your custom control, Intellisense has no idea that something can go inside that tag, and likewise the dynamic compiler will throw up errors.

You don't want to reinvent the wheel, however, by recreating those child elements. The solution? Inheritence.

Let's take an ASP Table control for example, since that's the one I've been working on for the past few days. What I wanted to do was to create a sort of wrapper around the table so that all my tables would have the same graphics without having to put the same code over and over in my .aspx files. I also added a title property, and thought about future development where I might want to create various themes for the site. This all can be done easily in a custom control.

Now, the basic child elements of the Table control are the TableRow and TableCell elements. In order to be able to use them, I must extend them in the same assembly as my Table control. Here's what I've done.

Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports Microsoft.VisualBasic

Namespace MyControls

    Public Class MyTable
        Inherits Table

        Private strTitle As String

        Public Property Title() As String
            Get
                Return strTitle
            End Get
            Set(ByVal value As String)
                strTitle = value
            End Set
        End Property

        Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
            'Do your custom writing here!
            writer.Write(strTitle)
            'Do your custom writing here!
            MyBase.Render(writer)
            'Do your custom writing here!
        End Sub

    End Class

    Public Class MyTableRow
        Inherits TableRow
    End Class

    Public Class MyTableCell
        Inherits TableCell
    End Class

End Namespace


Note that the classes for the child elements are otherwise empty. They simply inherit from the parent and that's it. Since the Table control is looking to have a TableRow inside of it, and MyTableRow inherits from TableRow, you can now use MyTableRow and Intellisense will pick it up. Same for MyTableCell. What's the .aspx look like? Load up a quick page, and put this after the Master, Page, or Control directive:

<%@ Register Namespace="MyControls" TagPrefix="mc" %>


After that, throw this anywhere in the body:

<mc:MyTable ID="tblTest" runat="server" Title="Testing MyTable" Width="100%">
    <mc:MyTableRow BackColor="Yellow">
        <mc:MyTableCell HorizontalAlign="Center">
            This table is working!
        </mc:MyTableCell>
    </mc:MyTableRow>
</mc:MyTable>


You will notice that not only do you get Intellisense for the child elements and their attributes, you also get no more errors!

Comments

Loading...
roncli.com Media Player