Visual Inheritance in ASP.NET

Provide a Consistent and Reusable Interface





Visual Inheritance in ASP.NET

Provide a Consistent and Reusable Interface


By Dennis Butler


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


The implementation of inheritance is something that is usually 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-object structure relative to the data that is being captured or presented, compared to how that data is presented on screen to the user.


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


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


Windows Visual Inheritance with .NET

Although the purpose of this article is to focus on inheritance within ASP.NET and Web forms, it is worth taking a quick look at the 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 this article, I named the solution InheritanceSolution and named the Windows project WinInherit (the accompanying sample code is available for download; see end of article for details). To illustrate how visual inheritance works within the context of a single project, Figure 1 shows a screen capture of a sample form that has some controls and colors set.


Figure 1: Sample base class form screen.


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


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


Figure 2: The Inheritance Picker form.


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


Our second form appears to be almost an exact match to the first. The only outward differences on screen are the fact that inherited controls are marked with a small icon in the designer, and the Properties window shows the base class as inheriting from WinInherit.Form1 rather than System.Windows.Forms.Form.


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


public class Form1 : System.Windows.Forms.Form


 private Button btnCommon;

 private Label lblCommon;

 private StatusBar sbCommon;

Figure 3: Initial form member declarations (C#).


Friend WithEvents btnCommon As Button

Friend WithEvents lblCommon As Label

Friend WithEvents sbCommon As StatusBar

Figure 4: Initial form member declarations (VB.NET).


To allow descendant forms to modify properties, simply change 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 Button btnCommon;

 protected Label lblCommon;

 protected StatusBar sbCommon;

Figure 5: Modified form member declarations (C#).


Protected WithEvents btnCommon As Button

Protected WithEvents lblCommon As Label

Protected WithEvents sbCommon As StatusBar

Figure 6: Modified form member declarations (VB.NET).


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


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


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


Figure 7: Modifying descendant properties.


Because we ve broken the connection for the Size and Location properties, any changes to these properties on the parent form will not be reflected in the descendant form. However, all other properties are still synchronized with the parent form. For example, if we change the background color of the button on the parent form, rebuild, and open the descendant form in the designer, we ll see that the color has changed while the size and location remain in their altered state.


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


Figure 8: Reset modified descendant property.


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


private void btnCommon_Click(object sender, EventArgs e)


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


Figure 9: Simple button event (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 button event (VB.NET).


Clicking on the button in the descendant form will present the same message as when it is clicked from the parent form. Furthermore, we can extend the event code in the descendant form by adding an event to the button 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 form button event (C#).


Private Sub btnCommon_Click(ByVal sender As Object,

                           ByVal e As EventArgs)

                           Handles btnCommon.Click

 MessageBox.Show("And hello from Form 2.")

End Sub

Figure 12: Child form button event (VB.NET).


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


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


Web Visual Inheritance with ASP.NET

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


Web development is a wholly different creature as we all know. There isn t a simple set of visual controls that all Web environments share; presentation of data over the Web is the very definition of a heterogeneous visual user interface. Whether through client-side or server-side technologies, or through a combination of static HTML and dynamic information serving, or through any combination thereof, Web development often has to be done when many different technologies are all working together to present a common interface to the user.


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


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


So let s get started on some examples.


Within Visual Studio, within the existing solution of InheritanceSolution, I created a new project. This one was created as an ASP.NET Web application, named VBWebInherit. I started by creating a new Web form, as was done in the Windows example. I dropped a Label and Button onto the form 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 of the project similar to what we had for our Windows project. There is also no item within the Add New Item list (see Figure 14).


Figure 14: What? No Web form inheritance option?


So why is the capability to inherit directly from another ASP.NET page not included by default? Part of the reason for this is simply because our Web projects will not exclusively contain ASP.NET controls and components. In Windows, a common control set could be guaranteed; everything inherited from a common set of ancestor controls that were built into the presentation layer itself. The inheritance mechanism thus knows all information about the parent and descendant properties, and can control the presentation of those controls on screen.


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


Although the ability to descend from a parent form in a Web application is not natively supported, there are capabilities within ASP.NET that allow it to work that can be very useful in designing a reusable visual interface.


To show this in a simple example, let s create a new Web form within our project, named WebForm2.aspx. Within the code-behind page, let s change 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 void Page_Load(object sender, EventArgs e)


   // Put user code to initialize the page here

   msg.Text = "This is my new message.";     


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


Private Sub Page_Load(ByVal sender As Object,

                     ByVal e As EventArgs)

                     Handles MyBase.Load

 'Put user code to initialize the page here

 msg.Text = "This is my 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 start using members of the base class WebForm1 from within WebForm2. As shown in the code in Figures 15 and 16, we can immediately start to write code, referencing objects within the base class and assigning them.


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


Figure 17: Error on descendant Web form 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 Page object 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 parent form has thrown an error. Although we were able to reference the object in our Page_Load event and compile without error, the mechanisms within ASP.NET do not parse the parent aspx form at run time. Only the descendant aspx page is parsed when the page is called. Because there is no asp:Label object referenced as msg within the page, .NET throws an error.


The problem is that fundamentally, the Visual Studio environment does not allow this kind of visual inheritance. Non-visually, we can inherit as much as we want. We can create a System.Web.UI.Page object hierarchy with as many layers as are needed, as long as they don t include elements 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 not within the corresponding aspx page.


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


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


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



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

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

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


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


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


The solution to this particular problem lies in the fact that Web pages are themselves a product of blended technologies. Understanding how 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 aspx to the client as HTML. Because of this, we can put our inherited control within a server-side include and still have it correctly parsed and presented.


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


Figure 19: Add HTML for a server-side include.


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

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





Figure 20: Adding an include 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 is compromised by this method is the fact that individual properties that are set on ASP.NET controls within the aspx page itself do not get passed to descendant modules. This makes sense based on what we know about how the .NET process parses and presents the aspx page, compared to the code-behind source.


The best way to resolve this is to maintain as much appearance and layout information as possible within the C# or VB.NET code itself, rather than on the aspx page. Because all aspects of the object relation and inheritance model work perfectly on the programming code side of Web forms, any descendant forms will automatically load these properties and be presented correctly.


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


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 parent form properties to C#.


Private Sub Page_Load(ByVal sender As Object,

                     ByVal e As EventArgs)

                     Handles MyBase.Load

 'Put user code to initialize 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 parent form properties to VB.NET.


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


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


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



Visual inheritance for Web applications is not as straightforward as the equivalent concepts in Windows. The inherent differences in the structure of a Windows environment compared to a Web environment require that the .NET Framework approach inheritance differently. As such, the Windows framework for form inheritance is well thought-out and integrated within Visual Studio. The methods required to implement visual inheritance within Web pages are less well defined, and require some workarounds to implement.


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


The sample code in this article is available for download.


Dennis Butler is a Principal Consultant for Chalk Creek Software (, a software development consultancy that specializes in high-performance, data-centric Web and Windows application development. Dennis has written articles for several technical magazines and has presented at conferences in the US and worldwide. Dennis can 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 recent clients include the US Air Force, Starwood/ITT Sheraton Hotels, Harvard University, and the Watson Institute.




Hide comments


  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.