Visual Inheritance

Team-Fly    

 
Application Development Using Visual Basic and .NET
By Robert J. Oberg, Peter Thorsteinson, Dana L. Wyatt
Table of Contents
Chapter 12.  Advanced Windows Forms


Microsoft's .NET Framework supports an interesting new feature called Visual Inheritance. As you will recall from Chapter 5, inheritance allows you to build new classes that extend the functionality of their base class. In Windows Forms, Visual Inheritance allows you to create new forms by inheriting the appearance and functionality of existing forms. In the derived form, you can see the controls on the base form as well as add new controls. This is all accomplished using the Inherits keyword. For example, SomeNewForm can inherit the appearance, controls, events handling, etc. from SomeBaseForm by coding:

 graphics/codeexample.gif Public Class  SomeNewForm   Inherits SomeBaseForm  ... End Class 

In the following two subsections, we will discuss the development of a base form and a form that inherits the appearance and behavior of the base form.

Characteristics of the Base Form

The form that will serve as the base class for visual inheritance can be in the same project as the derived form or can be imported from another project. It can even be written in a different .NET language.

In this section, we will examine the Messages program. It is a VB.NET Class Library project and contains a form that will serve as our base class. Messages , shown in Figure 12-6, displays a list of status messages in a list box.

Figure 12-6. Designing a base class form for visual inheritance.

graphics/12fig06.jpg

Step 1: Create a Project with the Base Form

Because the form we are building has no practical use on its own (it displays status information of something else), we have decided to place it in a VB.NET Class Library project. However, we could also have chosen a Windows Application as the project type.

We must now design both the appearance and functionality of the form. Table 12-5 summarized the form's properties.

Table 12-5. Property Values for Visual Inheritance Demo
Control Type Name Other Properties
Panel panMessages  
Label lblMessages Text: Messages
Button btnClear Text: Clear
Listbox lstMessages  
Form MessageForm Text: Form1

Step 2: Determine the Controls Customizable by the Derived Class

As with all other applications involving inheritance, the access modifier that we specify greatly impacts which class members are accessible to the derived form. The Windows Forms Designer adds variables and code to a form when you drag a control from the toolbox, place it on the form, and configure its properties. The variables that represent the instances of the control are automatically defined using the Friend access modifier. In the Messages program, the following variables were defined at the end of step 1:

 Friend WithEvents panMessages As System.Windows.Forms.Panel  Friend WithEvents lblMessages As System.Windows.Forms.Label Friend WithEvents lstMessages As _                               System.Windows.Forms.ListBox Friend WithEvents btnClear As System.Windows.Forms.Button 

As you recall from Chapter 5, VB.NET defines several access modifiers for class members that impact the member's accessibility from derived classes. These modifiers include:

  • Public members are always accessible.

  • Protected members are accessible only to a derived class's implementation.

  • Friend members are accessible only from within the assembly that contains the class.

  • Private members are not accessible outside the class definition.

In order for a derived form to be able to interact with controls in a base form, the controls must be defined using an access modifier that makes them accessible:

  • If the base class form is in a different assembly, controls must be defined as Public .

  • If the base class form is in the same assembly as the derived form, controls may be defined using any modifier except Private .

In our Messages program, we will allow derived classes to control the label and button. Access to the list box will be provided via a publicly accessible method. Therefore, we must make the following changes to the control declarations:

  Private  WithEvents panMessages As _                                 System.Windows.Forms.Panel  Protected  WithEvents lblMessages As _                                System.Windows.Forms.Label  Private  WithEvents lstMessages As _                                System.Windows.Forms.ListBox  Protected  WithEvents btnClear As _                                System.Windows.Forms.Button 

Step 3: Implement the Base Form's Behavior

We must now add basic behavior to our form. In our case, we will add two methods , ClearMessages and AddToMessages , that allow access to the list box. We will also implement the Click event handler for btnClear .

  Public Sub ClearMessages()   lstMessages.Items.Clear()   End Sub   Public Sub AddToMessages(ByVal message As String)   lstMessages.Items.Add(message)   End Sub  Private Sub btnClear_Click(ByVal sender As Object, _  ByVal e As System.EventArgs) Handles btnClear.Click  lstMessages.Items.Clear()  End Sub 

Step 4: Building the Project

Finally, we must build the application. Because we are implementing a class library project, we will be building a DLL. The code is not immediately executable, so we will now shift our discussion to the development of the derived form.

Characteristics of the Derived Form

To use visual inheritance, a form must use the Inherits keyword to inherit features from another form. This means that it will inherit all of the control variables as well as the form behavior that has already been developed.

In this section, we will examine the Windows application CheckoutRegister . It will have a form that is derived from MessageForm in the Messages class library. That is, it uses a listbox to display status information.

The CheckoutRegister application maintains a list of items that are available for sale. It allows users to calculate the sales total of items that are purchased. A user enters the item number and clicks the Lookup button. The application searches the list of items and, if found, displays the description and price of the item. The user can then enter the number of units that are being purchased and click the Add Item button. This places the item total in the messages listbox. This process continues until the user clicks the Total Sales button, which displays the total due for all items purchased. The Clear button will be used to start a new sale. (See Figure 12-7.)

Figure 12-7. A form that uses visual inheritance.

graphics/12fig07.jpg

We have built the Items class to represent those items that are for sale. It implements the IComparable interface and overrides the Equals method (inherited from Object ) because we will use an ArrayList to manage the inventory and will be searching it to find items.

 graphics/codeexample.gif Public Class Items     Implements IComparable    Private m_ItemNo As Integer    Private m_Description As String    Private m_Price As Decimal    Public Sub New(ByVal itemNo As Integer, ByVal _     description As String, ByVal price As Decimal)       m_ItemNo = itemNo       m_Description = description       m_Price = price    End Sub    Public ReadOnly Property ItemNo() As Integer       Get          Return m_ItemNo       End Get    End Property    Public ReadOnly Property Description() As String       Get          Return m_Description       End Get    End Property    Public ReadOnly Property Price() As Decimal       Get          Return m_Price       End Get    End Property    Public Overloads Function CompareTo(ByVal obj As _     Object) As Integer Implements IComparable.CompareTo       Dim it As Items = CType(obj, Items)       If it.ItemNo < Me.ItemNo Then          Return -1       ElseIf it.ItemNo = Me.ItemNo Then          Return 0       Else          Return 1       End If    End Function    Public Overloads Overrides Function Equals(_     ByVal obj As Object) As Boolean       Dim it As Items = CType(obj, Items)       Return it.ItemNo = Me.ItemNo    End Function End Class 

Step 1: Create a Project that Uses Visual Inheritance

We begin by building a Windows application named CheckoutRegister . When it is created, a blank form named Form1 is generated for you. Remove Form1 from the application by right-clicking on the form in the Solution Explorer window and choosing Delete. We will replace this form with a form that uses virtual inheritance. Now add the code for the Items class discussed previously.

Now we are ready to build a form that inherits from MessageForm . Because this form is in a different assembly, we must first add a reference to that assembly. (This would not be necessary if the base form were in this project.) To add a reference to the Messages project, right-click the CheckoutRegister project in the Solution Explorer and select Add Reference. (See Figure 12-8.)

Figure 12-8. Adding a reference to another .NET assembly.

graphics/12fig08.jpg

In the References dialog box, switch to the Projects tab and click the Browse button to find Messages.dll . Click OK to add the reference. (See Figure 12-9.)

Figure 12-9. Specifying the .NET assembly containing the base class.

graphics/12fig09.jpg

Step 2: Adding an Inherited Form

To add the startup form of the CheckoutRegister application, we must now add an Inherited Form to the project. Right-click on the CheckoutRegister project and select Add Inherited Form. Name the form CheckoutRegisterForm (see Figure 12-10).

Figure 12-10. Adding an inherited form.

graphics/12fig10.jpg

In the Inheritance Picker dialog, select MessagesForm from the Messages project as the form to inherit from (see Figure 12-11). This will generate the following code:

 Public Class CheckoutRegisterForm     Inherits Messages.MessageForm    ... End Class 
Figure 12-11. Specifying the inherited form's base class.

graphics/12fig11.jpg

You must now design the form to resemble Figure 12-12. You should notice that the new form already looks just like MessageForm . You may resize it and the message panel stays docked at the bottom of the form. You should notice that the inherited buttons have a special icon in their upper-left corner, indicating they are inherited. Controls that were nonprivate in the base form can be manipulated. The label and button have resize handles to indicate you can manipulate them, change their properties and so on; however, the private panel and listbox are grayed out.

Figure 12-12. Designing the derived form.

graphics/12fig12.jpg

Table 12-6 summarizes the controls you must add to the form and their properties.

Table 12-6. Property Values for CheckoutRegisterForm
Control Type Name Other Properties
Label lblItemNo Text: Item No
Textbox txtItemNo Text: (blank)
Button btnLookup Text: Lookup
Label lblDescription Text: Description
Textbox txtDescription

Enabled: False

Text: (blank)

Label lblPrice Text: Price
Textbox txtPrice

Enabled: False

Text: (blank)

Label lblQuantity Text: Quantity
Textbox txtQuantity Text: (blank)
Button btnAddItem Text: Add Item
Button btnTotalSale Text: Total Sale
INHERITED LABEL lblMessages Text: Receipt
Form CheckoutRegisterForm

AcceptButton: btnLookup

Text: Checkout Register

Step 3: Coding the Inherited Form

To get our CheckoutRegister application working, we must add behavior to interact with the items that are for sale. To begin with, we will add an ArrayList to the form and initialize it to include a small inventory. We will also add a variable to represent the running total of the current sale.

 Public Class Register     Inherits Messages.MessageForm  Private inventory As New ArrayList()   Private currentTotal As Decimal  ...    Public Sub New()       ...  inventory.Add(New Items(101, "Hammer", 21.95))   inventory.Add(New Items(102, "Plyers", 14.95))   inventory.Add(_   New Items(103, "Flat screwdriver", 11.95))   inventory.Add(_   New Items(104, "Philips screwdriver", 11.95))   inventory.Add(New Items(105, "Wrench", 15.95))   inventory.Add(New Items(106, "Awl", 12.95))   inventory.Add(New Items(107, "Saw", 43.95))   inventory.Add(New Items(108, "Hacksaw", 26.95))   inventory.Add(New Items(109, "Wire cutters", 21.95))   inventory.Sort()  End Sub    ... End Class 

When the user clicks on the Lookup button, we must use the item number that was entered in the textbox to locate the corresponding item in the inventory array.

 Private Sub btnLookup_Click(ByVal sender As _   System.Object, ByVal e As System.EventArgs) _  Handles btnLookup.Click  Try   Dim itemNo As Integer = _   Convert.ToInt32(txtItemNo.Text)   Dim searchItem As New Items(itemNo, "", 0)   Dim foundAt As Integer = _   inventory.BinarySearch(searchItem)   If foundAt >= 0 Then   Dim foundItem As Items = _   CType(inventory(foundAt), Items)   txtItemNo.Text = foundItem.ItemNo   txtDescription.Text = foundItem.Description   txtPrice.Text = foundItem.Price   Else   Throw New Exception("Item not found!")   End If   Catch errObj As Exception   MessageBox.Show(errObj.Message)   End Try  End Sub 

We must add code in the Click event handler of btnAddItem to add price information to the messages listbox. We can access the listbox via the inherited method AddToMessages .

 Private Sub btnAddItem_Click(ByVal sender As _   System.Object, ByVal e As System.EventArgs) _  Handles btnAddItem.Click  Try   Dim qty As Integer = _   Convert.ToInt32(txtQuantity.Text)   Dim price As Decimal = _   Convert.ToDecimal(txtPrice.Text)   Dim lineTotal As Decimal = qty * price   Dim s As String   s = String.Format(_   "{0,8:c}  {1} unit(s) of item {2}({3}) at {4:c}", _   lineTotal, qty, txtItemNo.Text, _   txtDescription.Text, price)   AddToMessages(s)   currentTotal += lineTotal   txtItemNo.Text = ""   txtDescription.Text = ""   txtPrice.Text = ""   txtQuantity.Text = ""   Catch errObj As Exception   MessageBox.Show(errObj.Message)   End Try  End Sub 

We must also add code in the Click event handler of btnTotalSale to put the current total in the messages listbox.

 Private Sub btnTotalSale_Click(ByVal sender As _   System.Object, ByVal e As System.EventArgs) _  Handles btnTotalSale.Click  Dim s As String   s = String.Format(_   "TOTAL SALE:  {0,8:c}  ", currentTotal)   AddToMessages(s)  End Sub 

As you saw, visual inheritance is based upon the widely utilized object-oriented principles of inheritance and extension. By recognizing common design elements across a set of forms, you can greatly reduce the amount of repetitive coding by designing forms that can be extended using visual inheritance.


Team-Fly    
Top
 


Application Development Using Visual BasicR and .NET
Application Development Using Visual BasicR and .NET
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 190

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net