Understand Visual Inheritance
Learn how to use visual inheritance to create reusable WinForms in VB.NET.
by Stan Schultes
Technology Toolbox VB.NET
Note: This article's sample code is written in VB.NET beta 2. Some code might need to change if you're using later versions of the tools.
VB.NET's visual inheritance lets you create forms for reuse. You control which form components are allowed to change in the inherited form. When you inherit a form, you also can extend its functionality with new features in its visual layout, as well as its properties and methods.
To demonstrate how inheritance can work for you, I'll show you how to build a reusable AboutBox form you can use both as a splash screen and as a standard About dialog box (see Figure 1). You'll see how to lock certain controls on the form, such as a corporate logo, and how to make other controls configurable on the inherited form. I'll also show you how to customize an inherited form's appearance for alternate uses. Download the sample code to follow along.
Begin by creating the base form as a class library. Create a new project of type Windows Application, naming it AboutBase. Right-click on AboutBase in the Solution Explorer window. Choose Properties from the popup menu, change the Output Type to Class Library, and click on the OK button. Rename Form1.vb to AboutBox.vb by right-clicking on the form in the Solution Explorer and selecting Rename. Click on the form designer and change the Name property to AboutBox in the Properties window. Change the form's Text property to the string "About" to give the form a default caption value, and set the StartPosition property to CenterParent.
Using my AboutBox design as a model, size the AboutBox form, set its FormBorderStyle property to FixedSingle, and set the ControlBox property to False. Add a button from the Windows Forms tab on the toolbox and name it btnOK. Set Text property=OK and Modifiers property=Family. The Modifiers property determines whether the control is modifiable on the inherited form (value=Family) or fixed (value=Private). Set the AboutBox form AcceptButton property to btnOK, making OK the default button on the form.
Add and arrange three labels on the form (see Figure 2). Two are fixed on inherited forms: lblApplicationInfo (Text=Application Info, Modifiers=Private) and lblCopyrightInfo (Text=Copyright Info, Modifiers=Private). The third can change on inherited forms: lblCustomInfo (Text=Custom Info, Modifiers=Family, Visible=False). Then add two PictureBox controls: picBar (Modifiers=Private, Size=48,160, Image=bluebar.bmp) and picLogo (Modifiers=Private, Size=32,32, Image=vsm-gs.bmp). Your own bitmaps will do as long as you size the picture boxes to fit. Select picBar and choose the Format | Order menu item; click on the cascading menu's Send To Back option to put the bar behind the logo image.
Add an event routine to the OK button by double-clicking on it in design view. Add this line to the butOK_Click routine to exit the AboutBox:
You create property procedures for each label control (ApplicationInfo, CopyrightInfo, and CustomInfo) and the form's title bar (TitleBarText). This way, you can set the text for each from the host app:
Public Property ApplicationInfo() As String
Set(ByVal Value As String)
lblApplicationInfo.Text = Value.Trim
Create property procedures to set the visibility of the OK button (ShowOKButton) and the optional label (ShowCustomInfo):
Public Property ShowCustomInfo() As Boolean
Set(ByVal Value As Boolean)
lblCustomInfo.Visible = Value
Build the AboutBox component with the Build | Build Solution menu item to create the custom namespace "AboutBox." A .NET namespace is an organizational structure for code components.
Create a Test App
Add another project to the current solution to test the AboutBox form component. Choose the File | Add Project menu item and set the new project name to AboutTest. Rename the default Form1.vb to frmMain.vb. Change the Name property to fmMain and the Text property to AboutTest Sample. Right-click on the AboutTest project in the Solution Explorer and choose Set as Startup Project. Right-click on the project again, choose Properties, select frmMain as the Startup Object, and click on OK.
To use AboutBox from the AboutTest app, add a reference to the form and an instance of the form to the app. Right-click on AboutTest in the Solution Explorer and choose Add Reference. In the Add Reference dialog, click on the Projects tab, choose the AboutBase namespace item, click on Select, then click on OK. Right-click on AboutTest and choose Add | Add Inherited Form. Choose the Inherited Form template, enter the name frmAbout.vb, and click on Open. In the Inheritance Picker dialog, choose the AboutBox component in the AboutBase namespace and click on OK.
Double-click on the new frmAbout in the Solution Explorer to show its form designer. Each control on the form displays with a glyph in the corner indicating its inheritance from the base form. Click on lblApplicationInfo, ensuring it displays with a solid border and no resizing handles. This means the control is locked on the base form; you can't change it on the inherited form. Click on lblCustomInfo; its resizing handles let you move and change the field size.
Right-click on frmAbout in the Solution Explorer. Choose View Code. You'll see this code at the top of the code module:
Public Class frmAbout
The Inherits statement means frmAbout is based on the AboutBox component's functionality contained in the AboutBase namespace.
Double-click on frmMain in the Solution Explorer to show its form designer. On the Windows Forms tab of the Toolbox, double-click on the MainMenu item to add a menu to frmMain. In the menu designer, type the string &File; where it says "Type Here," and in the Properties window, set the Name property to mnuFile. The "&;" before the F sets the keyboard shortcut for this menu item to Alt-F. On frmMain, click on the File menu item, press the down arrow, type E&xit;, and set its Name property to mnuFileExit. Double-click on the Exit item to jump into the mnuFileExit_Click event handler routine, shutting down the app with this code:
On the frmMain designer, click on Type Here (to the right of File). Enter &Help; (Name=mnuHelp). Below it, add &About; (Name=mnuHelpAbout). Double-click on the About item and add this code to the mnuHelpAbout_Click event handler:
Dim fA As New frmAbout()
fA.ApplicationInfo = "AboutTest"
fA.CopyrightInfo = "Copyright Here"
The ShowDialog method displays frmAbout as a modal dialog box. Press F5 to build and run the AboutTest app. Choose the Help | About menu item; you'll see the AboutBox with your text in the Application and Copyright fields. Click on OK to dismiss frmAbout, and exit the app with File | Exit.
Create a Splash Screen
Now let's see how to inherit the AboutBase form in a separate project and how to adapt this form's functionality to a splash screen. Start by creating a new project, called SplashTest. Change the default Form1.vb filename to frmSplashTest.vb. Set its name to frmSplashTest in the Properties window. Right-click on the SplashTest project in the Solution Explorer, then choose Properties. Set the Startup Object to frmSplashTest and click on OK. Add menus to SplashTest as you did in AboutTest's frmMain, including the mnuHelpAbout_Click event to display the About form.
Add the AboutBox to your new project by right-clicking on SplashTest in the Solution Explorer and choosing Add | Add Inherited Form. Name it frmAbout.vb and click on Open. In the Inheritance Picker dialog, click on the Browse button, navigate to your AboutBase\bin directory, and double-click on AboutBase.dll. Choose the AboutBox component name in the AboutBase namespace, and click on OK to add the new project's inherited form.
Double-click on the new frmAbout in the Solution Explorer to display the form designer. Add a label below lblCustomInfo, naming it lblStatusInfo (Text=Status Info, Modifiers=Family, Visible=False). This field will show status information on the splash screen during application startup. (The lblStatusInfo control you've added is not inherited from the base form, so it lacks a glyph in its corner.) Add a StatusInfo property to frmAbout, and add a call to the form's Refresh method in the Property Set to make the form update right away:
Public Property StatusInfo() As String
StatusInfo = lblStatusInfo.Text
Set(ByVal Value As String)
lblStatusInfo.Text = Value.Trim
Now add a Boolean SplashScreen property to frmAbout (see Listing 1). This sets the visibility of several form controls to customize frmAbout's use as a splash screen. Update SplashTest's AssemblyInfo.vb file to create default values for the AboutBox fields if you're using AboutBox's GetAssemblyAttributes routine from the sample code. Keep the SplashScreen property value in member variable m_bSplash.
Finally, add code to the frmSplashTest_Load event to display frmAbout as a splash screen (see Listing 2). This routine simulates startup operations, displaying timed messages in the StatusInfo field. Run SplashTest and watch StatusInfo on the splash screen during app startup.
As the SplashTest project demonstrates, you get all of AboutBox's functionality simply by inheriting the form. The StatusInfo label and property and SplashScreen property are local enhancements to the inherited AboutBox form. This shows how you can extend existing classes (including any of .NET Framework's).
Here's a test for your new inheritance skills: Try allowing the inherited form's logo bitmap to be changed and the form to be resized. It worked? Now you're ready to use inheritanceand I predict you'll find yourself employing it every day you write code.