Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
(ebook) Visual Studio .NET Mastering Visual Basic.pdf
Скачиваний:
120
Добавлен:
17.08.2013
Размер:
15.38 Mб
Скачать

A “REAL” CLASS 361

openFileDialog1.ShowDialog()

Console.writeline(objStrTools.ExtractPathName(OpenFileDialog1.FileName))

Console.WriteLine(objStrTools.ExtractFileName(OpenFileDialog1.FileName)) End Sub

Reusing the StringTools Class

Let’s see now how the StringTools class can be used in another project, without making the VB file with the class part of every project that requires this functionality. First, you must create the class’s executable file. Unlike Windows applications, classes are compiled into DLL files. Your project most likely contains a test form in addition to the class, so you must exclude the test form from the project. Right-click the name of the test form and select Exclude From Project. This action will exclude the file from the project. You project now contains the StringTools class only.

Classes can’t be executed on their own, so you must also change the type of the project. Right-click the name of the project and select Properties. In the Project Property Pages dialog box, change the project’s output type from Windows Application to Class Library. Then close the project’s property pages, open the Project menu, and select Build. This action will create the StringTools.dll file in the project’s Bin folder. This is the file you must reference in any project that requires the functionality of the StringTools class.

Start a new project, and choose Project Add Reference. On the dialog box that will appear, switch to the Projects tab and click the Browse button. Locate the Bin folder under the project’s folder, where you will find the StringTools.dll file. Select it and close all the dialog boxes. When you’re back to the project, you will see that the StringTools class has been added to the project. You can’t edit the class’s code, which means you can’t break it. You can even extend the functionality of the StringTools class by adding more members to it, without touching its code. The topic of building new classes based on existing ones is discussed in the later section “Inheritance.”

VB.NET at Work: The ClassContacts Project

In Chapter 4, I discussed briefly the Contacts application. This application uses a structure to store the contacts and provides four navigational buttons to allow users to move to the first, last, previous, and next contact. Now that you have learned how to use the ListBox control and how to use custom classes in your code, we’re going to revise the Contacts application. First, we’ll implement the contacts as a class. The fields of each contact (company name, contact name, and so on) will be implemented as properties. The advantage of implementing the contacts as classes, as opposed to structures, is that you can validate the values of the fields from within your class, and not rely on the application developer to validate the data before storing them to an instance of a structure.

Another advantage is that other developers can extend your class and add new properties, or methods, without having access to your code. You will see how to extend classes later in this chapter, in the section on inheritance.

We’ll also improve the user interface of the application. Instead of the rather simplistic navigational buttons, we’ll place all the company names in a sorted ListBox control. The user can easily locate the desired company and select it in the list to view the fields of the selected contact. The editing buttons at the bottom of the form work as usual. Figure 8.10 shows the revised Contacts application, which is the ClassContacts application you will find in this chapter’s CD folder.

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

362 Chapter 8 BUILDING CUSTOM CLASSES

Figure 8.10

The interface of the ClassContacts application is based on the ListBox control.

Make a copy of the Contacts folder from Chapter 4 and rename it to ClassContacts. Then open the application in the new folder and likewise rename the project from Contacts to ClassContacts. The next step is to delete the declaration of the Contact structure and add a class to the project.

Name the new class Contact and enter in it the code from Listing 8.28.

Listing 8.28: The Contact Class

<Serializable()> Public Class Contact

Private _companyName As String

Private _contactName As String

Private _address1 As String

Private _address2 As String

Private _city As String

Private _state As String

Private _zip As String

Private _tel As String

Private _email As String

Private _URL As String

Property CompanyName() As String

Get

CompanyName = _companyName

End Get

Set(ByVal Value As String)

If Value Is Nothing Or Value = “” Then

Throw New Exception(“Company Name field can’t be empty”)

Exit Property

End If

_companyName = Value

End Set

End Property

Property ContactName() As String

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

A “REAL” CLASS 363

Get

ContactName = _contactName End Get

Set(ByVal Value As String)

_contactName = Value End Set

End Property

Property Address1() As String Get

Address1 = _address1 End Get

Set(ByVal Value As String) _address1 = Value

End Set

End Property

Property Address2() As String Get

Address2 = _address1 End Get

Set(ByVal Value As String) _address2 = Value

End Set

End Property

Property City() As String Get

City = _city End Get

Set(ByVal Value As String) _city = Value

End Set

End Property

Property State() As String Get

State = _state End Get

Set(ByVal Value As String) _state = Value

End Set

End Property

Property ZIP() As String Get

ZIP = _zip End Get

Set(ByVal Value As String) _zip = Value

End Set

End Property

Property tel() As String

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

364 Chapter 8 BUILDING CUSTOM CLASSES

Get

tel = _tel

End Get

Set(ByVal Value As String)

_tel = Value

End Set

End Property

Property EMail() As String

Get

EMail = _email

End Get

Set(ByVal Value As String)

_email = Value

End Set

End Property

Property URL() As String

Get

URL = _URL

End Get

Set(ByVal Value As String)

_URL = Value

End Set

End Property

Overrides Function ToString() As String

If _contactName = “” Then

Return _companyName

Else

Return _companyName & vbTab & “(“ & _contactName & “)”

End If

End Function

End Class

The first thing you’ll notice is that the class’s definition is prefixed by the <Serializable()> keyword. The topic of serialization is discussed in Chapter 11, but for now all you need to know is that the .NET Framework can convert objects to a text or binary format and store them in files. Surprisingly, this process is quite simple. <Serializable()> is an attribute of the class. As you will see later in this book, there are more attributes you can use with your classes, or even with your methods. The most prominent method attribute is the <WebMethod> attribute, which turns a regular function into a Web method.

The various fields of the contact structure are now properties of the Contact class. The implementation of the properties is trivial, except for the CompanyName property, which contains some validation code. The Contact class requires that the CompanyName property has a value; if it doesn’t, the class throws an exception. Finally, the class provides its own ToString method, which returns the name of the company followed by the contact name in parentheses. We’re going to store all the contacts in the ListBox control. The ListBox control will display the value returned by the object’s ToString

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

A “REAL” CLASS 365

method, so we must provide our own ToString method that describes each contact. The company name should be adequate, but if there are two companies by the same name, you can use another field to differentiate them. I’ve used the contact name, but you can use any of the other properties (the URL would be a good choice).

Each contact is stored in a variable of the Contact type and added to the ListBox control. Now, we must change the code of the main form a little. First, remove the navigational buttons; we no longer need them. Their function will be replaced by a few lines of code in the ListBox control’s SelectedIndexChanged event. Every time the user selects another item on the list, the statements shown in Listing 8.29 display the contact’s properties on the various TextBox controls on the form.

Listing 8.29: Displaying the Fields of the Selected Contact Object

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged

currentContact = ListBox1.SelectedIndex ShowContact()

End Sub

The ShowContact() subroutine reads the object stored at the location specified by the currentContact variable and displays its properties on the various TextBox controls on the form.

When a new contact is added, the code creates a new Contact object and adds it to the ListBox control. When a contact is edited, a new Contact object replaces the currently selected object on the control. The code is very similar to the code of the Contacts application. I should mention that the ListBox control is locked while a contact is being added or edited, because it doesn’t make sense to select another contact at that time. Besides, we want to be able to replace the contact being edited when the user is done.

To delete a contact (Listing 8.30), we simply remove the currently selected object on the control. In addition, we must select the next object, or the first object if the deleted object was the last one in the list.

Listing 8.30: Deleting an Object on the ListBox

Private Sub bttnDelete_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles bttnDelete.Click If currentContact > -1 Then

ListBox1.Items.RemoveAt(currentContact)

If currentContact = ListBox1.Items.Count Then _ currentContact = ListBox1.Items.Count - 1

If currentContact = -1 Then ClearFields()

MsgBox(“There are no more contacts”) Else

ShowContact() End If

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com

366 Chapter 8 BUILDING CUSTOM CLASSES

Else

MsgBox(“No current contacts to delete”)

End If

End Sub

When you add a new contact, the following code is executed in the Add button’s Click event handler:

Private Sub bttnAdd_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles bttnAdd.Click adding = True

ClearFields()

HideButtons() ListBox1.Enabled = False

End Sub

These statements simply prepare the application to accept a new record. The controls are cleared in anticipation of the new record’s fields, and the adding variable is set to True. The OK button is clicked to end either the addition of a new record or an edit operation. The code behind the OK button is shown in Listing 8.31.

Listing 8.31: Committing a New or Edited Record

Private Sub bttnOK_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles bttnOK.Click

Dim contact As New Contact()

SaveContact()

ListBox1.Enabled = True

ShowButtons()

End Sub

As you can see, the same subroutine handles both the insertion of a new record and the editing of an existing one. All the work is done by the SaveContact() subroutine, which is shown in Listing 8.32.

Listing 8.32: The SaveContact() Subroutine

Sub SaveContact()

Dim contact As New Contact() contact.CompanyName = txtCompany.Text contact.ContactName = txtContact.Text contact.Address1 = txtAddress1.Text contact.Address2 = txtAddress2.Text contact.City = txtCity.Text contact.State = txtState.Text contact.ZIP = txtZIP.Text contact.tel = txtTel.Text

Copyright ©2002 SYBEX, Inc., Alameda, CA

www.sybex.com