The Problem: Can you create reusable composite web user controls?

Yes, you can!

If you are like me, you like to get most bang for your code. In the object oriented world you get this by creating reusable objects. I recently started using web user controls in ASP.Net An ASP.NET Web user control is similar to a complete ASP.NET Web page (.aspx file), with both a user interface page and code. You can read all about its creation on MSDN site.

I decided to take it up one notch by creating a complex class of web user control by deriving it from another web user control class. I have done this kind of thing all the time with Windows Forms controls. I was expecting it to work the same way. So, it turned out that true inheritance is not possible with web user controls. The markup is not inherited at all. Much has been explained and discussed on the forums and blogs about this behavior. Some say it is by design and others have suggested hacks around it by instantiating the controls manually. I tinkered with it. Even though automatic true inheritance may not be possible with web user controls, you can achieve it by doing the following:
  1. Embed your base class control on your "derived" control. This will bring in the markup from the base control and its methods and properties (with no exposure to the outside world.)
  2. Expose the methods and properties of your base control using one of the two methods:
    • Manually expose what needs to be exposed. This means writing some (may be a lot) code, or
    • Expose the entire base control as an independent object. This will expose all the public methods and properties of the base control. This may not be a desirable thing to do, but it requires virtually no coding.
I have a small sample for you. In this sample I start with a base web user control class, the Vehicle, which has a few common properties like its type, image etc. I will derive the Bus and the Boat classes from it. Finally, I will add specific properties of the the bus and boat classes individually.  


Download the source code for the complete project.

Let us analyze the code. The Vehicle class has no surprises. It is a simple web user control with a few public properties, which I am using to set the text of the labels on the markup.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace LabWebUserControlInheritance
{
public partial class Vehicle : System.Web.UI.UserControl
{

    // Do not use constructors in user control except to initialize
    // private variables.

    // Exposing four properties of Vehicle class
    public string vehicleType
    {
        set
        {
            lblVehicleType.Text = value;
        }
    }
    public string fuelType
    {
        set
        {
            lblFuelType.Text = value;
        }
    }
    public string vehicleName
    {
        set
        {
            lblVehicleName.Text = value;
        }
    }
    public string vehicleImageFileName
    {
        set
        {
            imgVehicle.ImageUrl = @"images/" + value;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }
}
}
Code for the Boat class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace LabWebUserControlInheritance.Controls
{
public partial class Boat : System.Web.UI.UserControl
{
    // Do not use constructors in user control except to initialize
    // private variables.

    // Removed the following statement from Bus.ascx.designer file and added it here as public
    // to expose the Vehicle1 as an object by itself.
    public global::LabWebUserControlInheritance.Vehicle Vehicle1;
    public string boatType
    {
        set
        {
            lblBoatType.Text = value;
        }
    }

    public string decks
    {
        set
        {
            lblDecks.Text= value;
        }
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        // Page init is the best place to set/override properties
        Vehicle1.vehicleType = "Type of vehicle: Boat";
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }
}
}
Code for the Bus class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace LabWebUserControlInheritance.Controls
{
public partial class Bus : System.Web.UI.UserControl
{
    // Do not use constructors in user control except to initialize
    // private variables.

    // Removed the following statement from Bus.ascx.designer file and added it here as public
    // to expose the Vehicle1 as an object by itself.
    public global::LabWebUserControlInheritance.Vehicle Vehicle1;

    public string wheels
    {
        set
        {
            lblWheels.Text = value;

        }
    }

    public string busRoute
    {
        set
        {
            lblBusRoute.Text = value;
        }
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        // Page init is the best place to set/override properties
        Vehicle1.vehicleType = "Type of vehicle: Bus";
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }
}
}
The way I implemented the base control, you will have to reference base class' properties through base class reference. See the example below:
Bus1.Vehicle1.fuelType = "Runs on natural gas";
        Bus1.Vehicle1.vehicleName = "NY City Transit Bus";
        Bus1.Vehicle1.vehicleImageFileName = "bus.png";
Download the source code for the complete project. Conclusion: Web user controls cannot be derived from other web user controls because the markup is not inherited. You can embed one web user control into another. You can expose the embedded control's properties and methods by either exposing the entire embedded object, or by selectively exposing its methods and properties by writing some code.
3

View comments

About Me
About Me
My Photo
Piscataway, New Jersey, United States
I am an electrical engineer by education and a software developer by profession. I like building electro-mechanical models. I also like grilling and barbecuing with passion. To burn my beer cals, I swim and run. I usually post my DIY projects on: http://www.instructables.com/member/kabira/
Blog Archive
Loading
Dynamic Views theme. Powered by Blogger.