Visual Inheritance in ASP.NET

Provide a Consistent and Reusable Interface

Dennis Butler

October 30, 2009

16 Min Read
ITPro Today logo in a gray background | ITPro Today

CoverStory

LANGUAGES:C# | VB.NET

ASP.NETVERSIONS: 1.1

 

Visual Inheritance in ASP.NET

Provide a Consistent and Reusable Interface

 

By Dennis Butler

 

Object-oriented programming techniques represent some ofthe most fundamental building blocks for developing organized, streamlined, andreusable applications. Most programmers are familiar with the four tenets ofobject orientation: abstraction, encapsulation, polymorphism, and inheritance. Ofthese four categories, this article will focus primarily on inheritance as amethod to provide a common, reusable, visual interface for Web and Windowsapplications. Specifically, this article will demonstrate the use of visualinheritance in both Windows and Web applications as a means to provide aconsistent and reusable interface for your users.

 

The implementation of inheritance is something that isusually not applied to the UI of a particular Web or Windows-based application.It is much easier to conceptualize and implement a multi-tiered, inherited-objectstructure relative to the data that is being captured or presented, compared tohow that data is presented on screen to the user.

 

The .NET Framework provides the capability to developapplications that adhere to all aspects of object orientation. Relative toinheritance, there are many built-in capabilities within .NET, and VisualStudio itself, that assist developers in creating these types of applications.

 

This article will outline examples and explanations ofinheritance within the IDE of Visual Studio 2003, using .NET 1.1. For thepurposes of this article both C# and VB.NET will be used for examples and codesamples.

 

Windows Visual Inheritance with .NET

Although the purpose of this article is to focus oninheritance within ASP.NET and Web forms, it is worth taking a quick look atthe capabilities of WinForm inheritance in .NET.

 

Starting with a new solution and a C# or VB.NET project,we can create a form with some custom properties. For the purposes of thisarticle, I named the solution InheritanceSolution and named the Windows projectWinInherit (the accompanying sample code is available for download; see end ofarticle for details). To illustrate how visual inheritance works within thecontext of a single project, Figure 1 shows a screen capture of a sample formthat has some controls and colors set.

 


Figure 1: Sample base class formscreen.

 

At this point, we have a starting point from which we canderive future forms. Before we can continue, though, we must save and build theproject to create the assembly binaries. These binaries are used by theinheritance wizard to allow selection of possible inherited forms. This comesinto play later when we make changes to our base form.

 

Now we ll inherit from this new form we created. Right-clickon the project in the Solution Explorer, and select Add | Add Inherited Formfrom the submenu that appears. This will bring up the Add New Item menu. Specifya class name for the new form and click Open. This will bring up theInheritance Picker form shown in Figure 2.

 


Figure 2: The Inheritance Pickerform.

 

Because we have only one form in this project, there isonly one form component from which we can inherit: our base form created in theprevious step. If we had multiple forms, or other visual controls within theproject, they would also appear in this list.

 

Our second form appears to be almost an exact match to thefirst. The only outward differences on screen are the fact that inheritedcontrols are marked with a small icon in the designer, and the Propertieswindow shows the base class as inheriting from WinInherit.Form1 rather thanSystem.Windows.Forms.Form.

 

The new form that has been created, Form2, does not bydefault allow the inherited controls to be modified. All properties in theProperties Inspector are disabled. The reason for this is because on our baseform, the controls are by default declared as private (C#) or Friend (VB) whenthey were dropped on the form (see Figures 3 and 4).

 

public class Form1 : System.Windows.Forms.Form

{

 private Button btnCommon;

 private Label lblCommon;

 private StatusBarsbCommon;

Figure 3: Initial formmember declarations (C#).

 

Friend WithEvents btnCommon As Button

Friend WithEvents lblCommon As Label

Friend WithEvents sbCommon As StatusBar

Figure 4: Initial formmember declarations (VB.NET).

 

To allow descendant forms to modify properties, simplychange the Modifiers properties for each control in the base form to Protected(C# and VB) and rebuild the project (see Figures 5 and 6).

 

public class Form1 : System.Windows.Forms.Form

{

 protected ButtonbtnCommon;

 protected LabellblCommon;

 protected StatusBarsbCommon;

Figure 5: Modifiedform member declarations (C#).

 

Protected WithEvents btnCommon As Button

Protected WithEvents lblCommon As Label

Protected WithEvents sbCommon As StatusBar

Figure 6: Modifiedform member declarations (VB.NET).

 

Now we ll see that the individual properties and valueswithin the Properties window for Form2 are all enabled and able to be modified.

 

Another aspect of WinForm visual inheritance worth notingis that the inherited properties are stored on a per-property basis. A descendantform object will inherit all controls from the parent form, and will inheritall individual properties of each control that has not been explicitlyoverwritten. This allows the user the ability to make property adjustments onthe descendant forms without completely breaking the link to the parent formfor the control.

 

For example, if we change the size of the button on ourdescendant form to be as wide as the form itself, the links to the Size andLocation properties of the button to the parent form will be broken. Once wemake this adjustment on the descendant form, we ll see the property values forSize and Location in bold in the Properties window, as shown in Figure 7. Thisis our sign that the default value has been modified.

 


Figure 7: Modifying descendantproperties.

 

Because we ve broken the connection for the Size andLocation properties, any changes to these properties on the parent form willnot be reflected in the descendant form. However, all other properties arestill synchronized with the parent form. For example, if we change thebackground color of the button on the parent form, rebuild, and open thedescendant form in the designer, we ll see that the color has changed while thesize and location remain in their altered state.

 

Once a property has been changed, it can be reset to thedefault parent value by right-clicking over the specific property in theProperties window and selecting Reset; this is shown in Figure 8.

 


Figure 8: Reset modified descendantproperty.

 

Written code is also inherited from the base form. Thiscan be shown by adding a simple event for the button click on the parent formForm1 (see Figures 9 and 10).

 

private void btnCommon_Click(object sender, EventArgs e)

{

 MessageBox.Show(this,"Hello from Chalk Creek Software");

}

Figure 9: Simple buttonevent (C#).

 

Private Sub btnCommon_Click(ByVal sender As Object,

                           ByVal e As EventArgs)

                           Handles btnCommon.Click

 MessageBox.Show("Hello from Chalk Creek Software")

End Sub

Figure 10: Simple buttonevent (VB.NET).

 

Clicking on the button in the descendant form will presentthe same message as when it is clicked from the parent form. Furthermore, wecan extend the event code in the descendant form by adding an event to thebutton on the descendant form, Form2 (see Figures 11 and 12).

 

private void btnCommon_Click(object sender, EventArgs e)

{

 MessageBox.Show(this,"And hello from Form 2.");

}

Figure 11: Child formbutton event (C#).

 

Private Sub btnCommon_Click(ByVal sender As Object,

                           ByVal e As EventArgs)

                           Handles btnCommon.Click

 MessageBox.Show("Andhello from Form 2.")

End Sub

Figure 12: Child formbutton event (VB.NET).

 

At this point, running the application and clicking on thebutton on Form2 will show both messages; first the parent message, then thedescendant message.

 

Although the examples here illustrate a simple example,these concepts and structures represent a powerful tool that can be used tokeep common controls, functionality, and a consistent look/feel throughout yourWindows applications.

 

Web Visual Inheritance with ASP.NET

There are many differences between Windows and Webdevelopment, and the concept and implementation of visual inheritance is nodifferent. The Windows framework inherently lends itself to the kind of visualinheritance previously shown. For the most part, a Windows form is ahomogeneous creature. All elements on a screen (again, for the most part) arepart of a common control set that has been in place by Microsoft since theorigin of Windows itself. Thus, implementing the capability for inheritance ona Windows form is much easier. The ability to inherit all aspects of a visualinterface is possible because of this common control set.

 

Web development is a wholly different creature as we allknow. There isn t a simple set of visual controls that all Web environmentsshare; presentation of data over the Web is the very definition of aheterogeneous visual user interface. Whether through client-side or server-sidetechnologies, or through a combination of static HTML and dynamic informationserving, or through any combination thereof, Web development often has to bedone when many different technologies are all working together to present acommon interface to the user.

 

The concept of reusing visual controls and streamlining Webdevelopment is not new, however. From the first days of HTML and Webdevelopment, there have been methods and tools in place to create somesemblance of visual inheritance on the Web. This includes, but certainly is notlimited to, various server-side includes (SSI, JSP includes, etc.), cascadingstyle sheets (CSS), and other code reuse mechanisms.

 

ASP.NET also has many similar built-in mechanisms tocreate visual inheritance. However, these implementations are certainly not asstraightforward as their Windows counterparts.

 

So let s get started on some examples.

 

Within Visual Studio, within the existing solution ofInheritanceSolution, I created a new project. This one was created as anASP.NET Web application, named VBWebInherit. I started by creating a new Webform, as was done in the Windows example. I dropped a Label and Button onto theform and changed some properties; the example screen is shown in Figure 13.

 


Figure 13: The sample Web form.

 

However, there is no simple shortcut on the Add submenu ofthe project similar to what we had for our Windows project. There is also noitem within the Add New Item list (see Figure 14).

 


Figure 14: What? No Web form inheritanceoption?

 

So why is the capability to inherit directly from anotherASP.NET page not included by default? Part of the reason for this is simplybecause our Web projects will not exclusively contain ASP.NET controls andcomponents. In Windows, a common control set could be guaranteed; everythinginherited from a common set of ancestor controls that were built into thepresentation layer itself. The inheritance mechanism thus knows all informationabout the parent and descendant properties, and can control the presentation ofthose controls on screen.

 

On the Web, however, full control over each element on a Webpage is simply not possible, because ASP.NET may not have explicit knowledge ofthe structure of HTML objects themselves. All aspects of presenting theeventual output may not be controlled by the ASP.NET engine.

 

Although the ability to descend from a parent form in aWeb application is not natively supported, there are capabilities withinASP.NET that allow it to work that can be very useful in designing a reusablevisual interface.

 

To show this in a simple example, let s create a new Webform within our project, named WebForm2.aspx. Within the code-behind page, let schange the inheritance of the page to descend from WebInherit.WebForm1,replacing System.Web.UI.Page, and write a line of code (see Figures 15 and 16).

 

public class WebForm2 : WebInherit.WebForm1

{

 private voidPage_Load(object sender, EventArgs e)

 {

   // Put user code toinitialize the page here

   msg.Text = "Thisis my new message.";     

 }

Figure 15:Inheritance modification on a child form (C#).

 

Private Sub Page_Load(ByVal sender As Object,

                     ByVale As EventArgs)

                     Handles MyBase.Load

 'Put user code toinitialize the page here

 msg.Text = "This ismy new message."

End Sub

Figure 16:Inheritance modification on a child form (VB.NET).

 

We don t have to build the solution in order to startusing members of the base class WebForm1 from within WebForm2. As shown in thecode in Figures 15 and 16, we can immediately start to write code, referencingobjects within the base class and assigning them.

 

When we rebuild the application and try to launch our newWebForm2, however, we are greeted by the error screen shown in Figure 17.

 


Figure 17: Error on descendant Webform WebForm2.

 

Did we miss something? Well, going back to Visual Studio,we can see that there are no controls shown on the descendant form. The Pageobject of WebForm1 was correctly declared in our descendant form, WebForm2. Obviously,this is a different situation than what we were able to see in our WinForms.

 

The asp:Label object referenced as msg from the parentform has thrown an error. Although we were able to reference the object in ourPage_Load event and compile without error, the mechanisms within ASP.NET do notparse the parent aspx form at run time. Only the descendant aspx page is parsedwhen the page is called. Because there is no asp:Label object referenced as msgwithin the page, .NET throws an error.

 

The problem is that fundamentally, the Visual Studioenvironment does not allow this kind of visual inheritance. Non-visually, wecan inherit as much as we want. We can create a System.Web.UI.Page objecthierarchy with as many layers as are needed, as long as they don t includeelements that are presented on screen. On-screen elements are parsed at run time,so build errors are not created by code that references controls that are notwithin the corresponding aspx page.

 

However, there are a few tips to get around this. Forstarters, the easiest way is to simply put a redeclaration of the msg objectwithin the descendant WebForm2.aspx page. Doing this, we can use an objectdeclared in a base class and have it presented appropriately on screen.

 

Now loading the WebForm2.aspx page shows the content weexpect, based on the code within the Page_Load event.

 

At this point, we have created a bridge between our parentand descendant form. However, it is not perfect. Individual properties of thedescendant asp:Label object specified within the parent aspx page do not pulltheir properties from the parent form. Furthermore, if we use the designer onthe descendant WebForm2 page and rebuild, we get a build error (see Figure 18).

 

c:inetpubwwwrootVBWebInheritWebForm2.aspx.cs(19):

The keyword new is required on 'WebInherit.WebForm2.msg'

because it hides inherited member 'WebInherit.WebForm1.msg'

Figure 18: The builderror when using the designer on an inherited form.

 

Yet again, ASP.NET has attempted to foil our attempts atvisual inheritance using these methods. This error is the result of how theVisual Studio designer synchronizes presentation to code; it parses the aspx pageand declares objects within the code accordingly. We needed to put ourasp:Label msg object within the aspx page in order to access it through commoncode, but the designer complained about this declaration. If we had stayed inthe HTML view of the Web form designer, this problem would not have presenteditself.

 

All we need to do is go back to the child code-behindpage, remove the newly placed declaration for the msg object, recompile, and we reready to go. The downside to this approach is that every time the Web form designeris used instead of the HTML view, inherited controls will be redeclared anderror messages will result following compilation. With this in mind, is it evenworth continuing down this road? Absolutely.

 

The solution to this particular problem lies in the factthat Web pages are themselves a product of blended technologies. Understandinghow to make them fit together can resolve situations such as this.

 

For example, server-side include statements, such as a#include, are processed before the ASP.NET engine completes parsing of the aspxto the client as HTML. Because of this, we can put our inherited controlwithin a server-side include and still have it correctly parsed and presented.

 

Back in Visual Studio, let s create a new HTML page aspart of our WebInherit project (see Figure 19).

 


Figure 19: Add HTML for a server-sideinclude.

 

After we create our new file, msg.htm, we ll simply removethe asp:Label object of msg from the WebForm2.aspx file and put it into themsg.htm file.

Then we ll put a server-side include statement intoWebForm2.aspx, as shown in Figure 20.

 

 

 

 

Figure 20: Adding aninclude statement to a child form.

 

With this configuration, we can now compile, use the designer,and run this descendant Web page without errors. In more complicated examples,this can be used to present any combination of inherited controls on screen.

 

The last facet of visual inheritance for Web pages that iscompromised by this method is the fact that individual properties that are seton ASP.NET controls within the aspx page itself do not get passed to descendantmodules. This makes sense based on what we know about how the .NET processparses and presents the aspx page, compared to the code-behind source.

 

The best way to resolve this is to maintain as muchappearance and layout information as possible within the C# or VB.NET codeitself, rather than on the aspx page. Because all aspects of the objectrelation and inheritance model work perfectly on the programming code side of Webforms, any descendant forms will automatically load these properties and bepresented correctly.

 

In our parent form, all properties were removed from themsg object on the aspx page. In the Page_Load function of the C# and VB.NETsource, the code shown in Figures 21 and 22 was added to our parent formWebForm1.

 

private void Page_Load(object sender, EventArgs e)

{

 // from aspx:BackColor="DarkMagenta"

 //ForeColor="Yellow" Font-Bold="True"

 msg.BackColor =System.Drawing.Color.DarkMagenta;

 msg.ForeColor =System.Drawing.Color.Yellow;

 msg.Font.Bold = true;

}

Figure 21: Moving parentform properties to C#.

 

Private Sub Page_Load(ByVal sender As Object,

                     ByVale As EventArgs)

                     Handles MyBase.Load

 'Put user code toinitialize the page here

 ' from aspx:BackColor="DarkMagenta"

 'ForeColor="Yellow" Font-Bold="True"

 msg.BackColor =System.Drawing.Color.DarkMagenta

 msg.ForeColor =System.Drawing.Color.Yellow

 msg.Font.Bold = True

End Sub

Figure 22: Moving parentform properties to VB.NET.

 

Now when running the descendant form WebForm2, the colorsshow up correctly because of the inheritance. We can see this when we build theproject and load up WebForm2.

 

If we change the BackColor of msg to beSystem.Drawing.Color.Green in the parent form, then rebuild, we ll see this newcolor reflected in the parent and descendant form (see Figure 23).

 


Figure 23: Descendant form withparent form property information set in C#.

 

Conclusion

Visual inheritance for Web applications is not asstraightforward as the equivalent concepts in Windows. The inherent differencesin the structure of a Windows environment compared to a Web environment requirethat the .NET Framework approach inheritance differently. As such, the Windowsframework for form inheritance is well thought-out and integrated within VisualStudio. The methods required to implement visual inheritance within Web pagesare less well defined, and require some workarounds to implement.

 

ASP.NET 2.0 will provide far greater support for Web pagesthat use visual inheritance. The Master Pages feature will allow developers tocreate base user interfaces that can be inherited, extended, and nestedmultiple times, with full designer support in Visual Studio 2005. Until then,following these guidelines will help to streamline your Web applications, andbetter fit them within a traditional object-oriented hierarchy.

 

The sample code inthis article is available for download.

 

Dennis Butler is aPrincipal Consultant for Chalk Creek Software (http://www.chalkcreek.com), a softwaredevelopment consultancy that specializes in high-performance, data-centric Weband Windows application development. Dennis has written articles for severaltechnical magazines and has presented at conferences in the US and worldwide. Denniscan be reached at mailto:[email protected].Chalk Creek Software has offices in the greater Boston and Pittsburgh areas,and serves customers across a variety of industries. Some of their recentclients include the US Air Force, Starwood/ITT Sheraton Hotels, HarvardUniversity, and the Watson Institute.

 

 

 

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like