Article source code (both VB.NET and C#): visual_inherit.zip
Visual Inheritance is Microsoft's way to describe implementation inheritance of a visual object such as Windows Forms. This may sound complex if you are just moving from VB6, but the concept is similar to using an ActiveX control on a VB6 form. The difference is reusability at the form level.
Inheriting forms is a powerful feature that allows cross-project standardization of common elements on a form that may be changed in one place rather than in countless individual forms. For example, I once had to re-order the buttons on several dozen forms so the buttons flowed left to right as Help, OK, and Cancel instead of OK, Cancel, and Help. If I had used a base Windows Form, I could have changed the order on the base form, re-compiled, and been done with it.
In the following example you will create a form, add controls, save the form in a class library, and inherit that form in another project. VB.NET is shown here but the steps are similar if using C#. You will find both VB.NET and C# implementation in the article code.
In Visual Studio .NET, go to the main menu and select File > New > Blank Solution. Name it
VisualInheritanceExample, and click OK.
Create the Base Project
Go to File > Add Project > New Project and select a
Windows Application project. Name it
StandardCompanyForms, and click OK. Go to View > Solution Explorer and select the
Form1.vb. Right-mouse click and select Rename. Change the name to
OKCancelForm.vb. Note that this is the name of the file not of the form itself. The properties you set in the form (except for the Name property) will be the defaults when you inherit the form.
Select the form in the design editor, go to View > Properties Window, and make changes so you have the following properties:
|Text||Standard Company Form|
Go to View > Toolbox to show the available controls. Drag and drop a panel control onto the form. The panel control acts as a container for other controls. It is similar to the GroupBox control but does not have a caption. One great feature of a panel is the
AutoScroll property that allows scroll bars to appear if the panel contains more controls than can be seen all at once. You won't use that feature in this example but it is something to keep in mind.
By setting the
Dock property of the panel to the bottom of the form, the controls you add will always stay at the bottom even after resizing the form. More on this later.
Drag and drop three buttons onto the panel control you added so the panel will act as their container. Setting the
Anchor property makes the buttons maintain a consistent relative location during form resizing.
Add Button Event Code
buttonOK to generate the click event in the code editor, and add code to close the form when the OK button is clicked.
Private Sub buttonOK_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles buttonOK.Click
To add a click event for while still in the code editor, click the Class Name dropdown and select
buttonCancel from the list. The Method Name dropdown fills with available events. Select
Click from the list.
Add code to prompt the users if they really wanted to cancel. A message box with a
Yes button and a
No button will appear. If the user clicks
No, then nothing happens. If the user clicks
Yes, then the form is closed.
Private Sub buttonCancel_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles buttonCancel.Click
Dim result As DialogResult
result = MessageBox.Show("Are you sure you want to cancel?", _
"Standard Company Caption", MessageBoxButtons.YesNo, _
If result = DialogResult.Yes Then
If you want to associate the user hitting the
Escape key with
buttonCancel, go to the design editor, select the form, and change the
CancelButton property to
Now create a click event for
buttonAbout to show some information about the base program. This gives you a starting point for returning information about your program. A word of warning though, you will receive a security error at runtime if executing on a different machine across a network. The
StringBuilder class provides highly optimized string concatenation.
Private Sub buttonAbout_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles buttonAbout.Click
Dim objVersionInfo As FileVersionInfo = FileVersionInfo.GetVersionInfo( _
Dim objStringBuilder As System.Text.StringBuilder = New _
"Standard Company Caption", MessageBoxButtons.OK, _
Go to the Solution Explorer and select the
StandardCompanyForms project. Right-mouse click and select "Properties" to make the Property Pages UI appear. Note that the Properties item does not appear on the Project menu unless the project item itself is selected. Change the selected item in the startup object dropdown to be
formOKCancel, and click OK. You need to do this because you changed the name of the default form.
Go to Debug > Start to run the project, and see how it works. Maximize the form and observe the button locations. Click on each of the buttons.
You are now ready to change the Windows Application project to a Class Library. You could have started this project as a class library but then you would not have been able to run the form until you inherited it.
Select the project
StandardCompanyForms in the Solution Explorer, and then select Project > Properties from the main window. On the General property page change the output type from Windows Application to Class Library, and click OK.
Rebuild (recompile) your project. This step is very important. When the project is rebuilt the code is output in a DLL instead of an EXE. If you don't do this step you will not be able to inherit the form in another project.
Create the Deriving Project
On the main menu select File > Add Project > New Project. Choose Windows Application and name it
CustomForms. This is the project that will include derived (inherited) forms.
In the Solution Explorer, select the default
Form1.vb that was created and delete it. Select the
CustomForms project in the Solution Explorer, and right-mouse click to display the shortcut menu. Select Add > Add Inherited Form. The Add New Item UI will appear. Change the name of the form to be created to
formInheritedCompanyStandard, then click OK.
The Inheritance Picker UI appears and displays the available components to inherit. Since there is only one, click OK. This adds a reference in the new project to the StandardCompanyForms class library, and creates a form identical to the one in the class library. The controls on the form have small arrows in the upper left hand corner indicating that they are inherited. Hover the mouse over a control to see a tooltip such as "Inherited control (Private)". If you had changed the Modifiers property in the original control, to Protected or Public you would be able to change its properties, such as size, in the inherited form (though you would not be able to delete it).
CustomForms project in the Solution Explorer, and right-click to display the shortcut menu. Select "Set as Startup Project". The project name should now be in bold font.
If you run the code without going to the Project Properties and changing the startup form, you will receive an error. The Task List will show "'Sub Main' was not found in 'CustomForms.Form1'". Double-click the item in the Task List to bring up the Startup Object UI. Select
CustomForms.formInheritedCompanyStandard and click OK. Run the code. The form should appear and behave as it did previously.
You are now ready to add your own controls to the form. If you make changes to the base
formOKCancel, you will need to recompile that project before your changes will appear in the inherited forms
A Word of Warning
You should carefully plan the content and behavior of your base form before inheriting from it. You need to leave enough room to contain all possible controls that you may add later. You are not able to overlap controls in the inherited form so using a panel control docked to the bottom means that no additional controls can be placed on the bottom of the inherited form.
To demonstrate the reason to use a panel control, add a new button on the base form (
formOKCancel) just above the panel control. Set the Anchor property to Bottom. Rebuild the project. Resize the inherited form (
formInheritedCompanyStandard) in the design editor so its height is doubled.
Go back to the base form and move the new button a few pixels to the left. Rebuild the project. When you return to the inherited form the new button is at the pixel location not the relative location that you might have expected. Resize the form and see that the offsets are assumed to be from this pixel location.
Visual inheritance can be a powerful means of reuse allowing you to make design and code changes in one location and have it apply across multiple forms. But, as with all things, caution and planning should be used to implement it in the most effective fashion.
Related devCity.NET articles: