Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Visual Basic 2005 (2006)

.pdf
Скачиваний:
219
Добавлен:
17.08.2013
Размер:
14.97 Mб
Скачать

Chapter 5

5.Next, modify the Remove method as follows:

‘Remove a customer from the collection

Public Sub Remove(ByVal oldCustomer As Customer) Me.List.Remove(oldCustomer)

‘Remove customer from the Hashtable EmailHashtable.Remove(oldCustomer.Email)

End Sub

6.Now add the RemoveAt method to override the default method defined in the

CollectionBase class:

‘Provide a new implementation of the RemoveAt method Public Shadows Sub RemoveAt(ByVal index As Integer)

Remove(Item(index))

End Sub

7.Run the project and click the Test button to load the customers. Click the Test button again to have the existing list of customers cleared before the customers are added again. Notice that this time no exception has been thrown.

How It Works

The exception isn’t thrown the second time around, because you are now making sure that the Hashtable and the internal list maintained by CollectionBase are properly synchronized. Specifically, whenever your CustomerCollection list is cleared using the Clear method, you make sure that the Hashtable is also cleared.

To clear the internal list maintained by CollectionBase, you ask the base class to use its own Clear implementation rather than trying to provide your own implementation. You do this by calling MyBase.Clear(). Right after that, you call Clear on the Hashtable:

‘Provide a new implementation of the Clear method Public Shadows Sub Clear()

‘Clear the CollectionBase MyBase.Clear()

‘Clear your hashtable EmailHashtable.Clear()

End Sub

You’ll also find that when you delete items from the collection by using Remove, the corresponding entry is also removed from the Hashtable, because of this method that you added:

‘Provide a new implementation of the RemoveAt method Public Shadows Sub RemoveAt(ByVal index As Integer)

Remove(Item(index)) End Sub

The Shadows keyword indicates that this Clear procedure should be used instead of the Clear in the base class. The arguments and the return type do not have to match those in the base class procedure, even though they do here.

166

Working with Data Structures

You don’t need to worry too much about the details of Shadows and Overrides at this point, as they are discussed in detail in Chapter 10.

Case Sensitivity

It’s about this time that case sensitivity rears its ugly head again. If you run your project and click the Test button and then enter a valid email address in all uppercase letters, you’ll see a message box indicating that there is no customer with that email address.

You need to get the collection to ignore case sensitivity on the key. In the next Try It Out, you do this by making sure that whenever you save a key, you transform the email address into all lowercase characters. Whenever you look up based on a key, you transform whatever you search for into lowercase characters too.

Try It Out

Case Sensitivity

1.Open the Code Editor for the CustomerCollection class and make the highlighted change to the Add method:

‘Add a customer to the collection

Public Sub Add(ByVal newCustomer As Customer) Me.List.Add(newCustomer)

‘Add the email address to the Hashtable

EmailHashtable.Add(newCustomer.Email.ToLower, newCustomer)

End Sub

2.Now, find the overloaded Item property that takes an e-mail address and modify this code:

‘Overload Item property to find a customer by email address

Default Public ReadOnly Property Item(ByVal email As String) As Customer Get

Return EmailHashtable.Item(email.ToLower)

End Get

End Property

3.Next, find the Remove method and modify this code:

‘Remove a customer from the collection

Public Sub Remove(ByVal oldCustomer As Customer) Me.List.Remove(oldCustomer)

‘Remove customer from the Hashtable

EmailHashtable.Remove(oldCustomer.Email.ToLower)

End Sub

4.Run the project and click the Test button. Now if you enter a valid email address in all uppercase, the lookup will still work.

167

Chapter 5

How It Works

Back in Chapter 4 you saw how you could do case-insensitive string comparisons using the String.Compare method. You can’t use this technique here because the Hashtable is handling the comparison and, ideally, you don’t want to produce your own version of the comparison code that the Hashtable uses just to do a case-insensitive match.

You can use the ToLower method available on strings. This creates a new string in which all of the characters are transformed into the lowercase equivalent, so whether you pass DHILTON@SOMECOMPANY.COM or DHilton@SomeCompany.com in, you always get dhilton@somecompany.com out.

When you add an item to the collection, you can get ToLower to convert the e-mail address stored in the Customer structure so that it is always in lowercase:

‘Add the email address to the Hashtable EmailHashtable.Add(newCustomer.Email.ToLower, newCustomer)

Likewise, when you actually do the lookup, you also turn whatever value is passed in as a parameter into all lowercase characters:

Return EmailHashtable.Item(email.ToLower)

Providing you’re consistent with it, this action makes uppercase characters “go away” — in other words, you’ll never end up with uppercase characters being stored in the key or being checked against the key.

This technique for removing the problem of uppercase characters can be used for normal string comparisons, but String.Compare is more efficient.

Advanced Array Manipulation

At the beginning of this chapter, the concept of arrays was introduced. I’ve left some of the more advanced discussions on arrays until later in the chapter, namely those involving adjusting the size of an array and multidimensional arrays.

Being able to manipulate the size of an array from code, and being able to store complex sets of data in an array is important, but with .NET it’s far easier to achieve both of these using the collection functionality that the majority of this chapter has discussed. These next two sections are included for completeness and so that you can make the comparisons between the two for yourself.

Dynamic Arrays

When using an array, if you want to change its size in order to add items, or clean up space when you remove items, you need to use the ReDim keyword to make it a dynamic array. This is a short form of, not surprisingly, “redimension.” In the next Try It Out, you’ll reuse the Array Demo project you created at the start of the chapter and tweak it so that you can add new friends to the array after the initial array has been created.

168

Working with Data Structures

Try It Out

Using ReDim

1.Find and open the Array Demo project. Open the Code Editor for Form1 and modify the code in the AddItemsToList method so that it looks like this:

Sub AddItemsToList(ByVal arrayList() As String) ‘Enumerate the array

For Each strName As String In arrayList ‘Add the array item to the list

lstFriends.Items.Add(“[“ & strName & “]”)

Next End Sub

2.Run the project and click the Initializing Arrays with Values button. Your form should look like Figure 5-23.

Figure 5-23

3.Now, stop the project and make the highlighted change to the btnInitializingArraysWithValues_Click method:

Private Sub btnInitializingArraysWithValues_Click( _

ByVal sender As System.Object, ByVal e As System.EventArgs) _

Handles btnInitializingArraysWithValues.Click

‘Declare and populate an array

Dim strMyFriends() As String = {“Robbin”, “Bryan”, “Stephanie”, _ “Sydney”, “Katie”}

‘Make the strMyFriends array larger ReDim strMyFriends(6)

strMyFriends(5) = “Matt” strMyFriends(6) = “Jay”

‘List your friends AddItemsToList(strMyFriends)

End Sub

169

Chapter 5

4.Run the project and click the Initializing Arrays with Values button. Your form should look like the one shown in Figure 5-24.

Figure 5-24

How It Works

After defining an array of 5 items, you use the ReDim keyword to re-dimension the array to have an upper boundary of 6, which, as you know, gives it a size of 7. After you do that, you have two new items in the array to play with — items 5 and 6:

‘Make the strMyFriends array larger ReDim strMyFriends(6) strMyFriends(5) = “Matt” strMyFriends(6) = “Jay”

Then, you can pass the resized array through to AddItemsToList:

‘List your friends AddItemsToList(strMyFriends)

But, as you can see from the results, the values for the first five items have been lost. (This is why you wrapped brackets around the results — if the name stored in the array is blank, you still see something appear in the list.) ReDim does indeed resize the array, but when an array is redimensioned, by default all of the values in the array are cleared, losing the values you defined when you initialized the array in the first place.

You can solve this problem by using the Preserve keyword.

Using Preserve

By including the Preserve keyword with the ReDim keyword, you can instruct Visual Basic 2005 to not clear the existing items. One thing to remember is that if you make an array smaller than it originally was, data will be lost from the eliminated elements even if you use Preserve. In the next Try It Out, you use Preserve.

170

Working with Data Structures

Try It Out

Using Preserve

1.Open the Code Editor for Form1 and modify the btnInitializingArraysWithValues_Click method as follows:

‘Make the strMyFriends array larger

ReDim Preserve strMyFriends(6) strMyFriends(5) = “Matt” strMyFriends(6) = “Jay”

2.Run the project again and click the Initializing Arrays with Values button. You should now find that the existing items in the array are preserved, as shown in Figure 5-25.

Figure 5-25

Summar y

In this chapter, you saw some ways in which you could manage complex groups of data. You started by looking at the concept of an array, or rather, defining a special type of variable that’s configured to hold a one-dimensional list of similar items rather than a single item.

You then looked at the concepts behind enumerations and constants. Both of these can be used to a great effect in making more readable and manageable code. An enumeration lets you define human-readable, common-sense titles to basic variable types. So rather than saying “mode=3”, you can say “mode=My Modes.Menu”. Constants allow you to define literal values globally and use them elsewhere in your code.

You then looked at structures. These are similar to classes and are well suited for storing groups of items of information that all pertain to a particular thing or person. After looking at these, you moved on to look at various types of collections, including the basic ArrayList and then saw how you could build your own powerful collection classes inherited from CollectionBase. Finally, you looked at the Hashtable class and covered some of the less-commonly used array functionality.

171

Chapter 5

To summarize, you should know how to:

Define and redimension fixed and dynamic string arrays

Enumerate through arrays and find their upper dimension

Define an enumeration of values using the Enum class

Create and use structures to manipulate sets of related data

Use an ArrayList to hold any type of object

Use collections to manage sets of related data

Exercises

Exercise 1

Create a Windows Application that contains three buttons. Add an enumeration of three names to your code. For the Click event for each button, display a message box containing a member name and value from the enumeration.

Exercise 2

Create a Windows Application that contains a TextBox control and a Button control. At the form level, create a names array initialized with a single name. In the Click event for the button control, add the code to redimension the array by one element preserving the existing data, add the new name from the text box to the array and to display the last name added to the array in a message box.

Hint: To determine the upper boundary of the array, use the GetUpperBound(0) method.

172

6

Building Windows

Applications

When Microsoft first released Visual Basic 1.0, developers fell in love with it because it made building the user interface components of an application very simple. Instead of having to write thousands of lines of code to display windows — the very staple of a Windows application — developers could simply “draw” the window on the screen.

In Visual Basic (any version), a window is known as a form. With the .NET Framework, this form design capability has been brought to all of the managed languages as Windows Forms. You’ve been using these forms over the course of the previous five chapters, but you haven’t really given that much thought to them — focusing instead on the code that you’ve written inside them.

In this chapter, you’ll look in detail at Windows Forms and learn how you can use Visual Basic 2005 to put together fully featured Windows applications. In particular, you will look at:

Adding more features using buttons, text boxes, and radio buttons

Creating a simple toolbar and toolbar buttons to respond to events

Creating additional forms in a Windows Forms application

Note that on occasion you’ll hear developers refer to Windows Forms as Win Forms, which is a carry over from programming with Visual Basic 6.0 and earlier versions.

Responding to Events

Building a user interface using Windows Forms is all about responding to events (such as Click), so programming for Windows is commonly known as event-driven programming. To build a form, you paint controls onto a blank window called the Forms Designer using the mouse. Each of these controls is able to tell you when an event happens. For example, if you run your program and click a button that’s been painted onto a form, that button will say, “Hey, I’ve been clicked!” and give you an opportunity to execute some code that you provide to respond to that event. You have already been using this feature.

Chapter 6

Setting Up a Button Event

A good way to illustrate the event philosophy is to wire up a button to an event. An example would be the Click event, which is fired whenever the button is clicked. You have more events than just the Click event, although in day-to-day practice it’s unlikely you’ll use more than a handful of these. Even though you’ve already seen the Click event in action, this next Try It Out will go into some of the details of Code Editor and some more Button events that you have not seen up until this point.

Try It Out

Using Button Events

1.Start Visual Studio 2005 and select File New Project from the menu. In the New Project dialog box, select Visual Basic as the Project Type and Windows Application as the Templates type. Enter a project name of Hello World 2 in the Name field and then click the OK button.

2.Click the form, and then, in the Properties window, change the Text property from Form1 to

Hello, world! 2.0.

3.From the Toolbox, drag a Button control onto the form. Change its Text property to Hello, world! and its Name property to btnSayHello. Resize your button so that it looks similar to the one shown in Figure 6-1.

Figure 6-1

4.Double-click the button and add the following highlighted code to the Click event handler:

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

ByVal e As System.EventArgs) Handles btnSayHello.Click

‘Display a MessageBox

MessageBox.Show(“Hello, world!”, Me.Text)

End Sub

5.Drop down the list in the Class Name combo box at the top of the code window. You’ll see the options shown in Figure 6-2. Select Form1 in the Class Name combo box.

Figure 6-2

Notice that the last two items in the list are slightly indented. This tells you that (Form1 Events) and btnSayHello are all related to Form1. That is, the btnSayHello class is a member of Form1. As you add more members to the form, they will appear in this list.

174

Building Windows Applications

6.Before you continue, take a quick look at the list in the Method Name combo box to the right of the Class Name combo box. Drop it down, and you’ll see the options shown in Figure 6-3. These options are described in the list that follows the figure.

Figure 6-3

The contents of the Method Name combo box change depending on the item selected in the Class Name combo box. This list lets you navigate through the methods related to the class you select in the Class Name combo box. In this case, its main job is to show you the methods and properties related to the class.

The (Declarations) entry takes you to the top of the class where you can change the definition of the class and add member variables.

The New method will create a new constructor for the class that you are working with. The constructor should contain any initialization code that needs to be executed for the class.

The Finalize method will create a new method called Finalize and add it to the class and will be called when your program ends to release any unmanaged resources.

The Dispose method takes you to the Dispose method for the class that you are working with and allows you to add any addition clean up code for your class.

The InitializeComponent method takes you to the code that initializes the controls for the class that you are working with. You should not modify this method directly. Instead, you should use the Form Designer to modify the properties of the controls on your form.

You’ll notice that Visual Basic 2005 adds a small icon to the left of everything it displays in these lists. These can tell you what the item in the list actually is. A small purple box represents a method, a small blue box represents a member, four books stacked together represent a library, three squares joined together with lines represent a class, and a yellow lightning bolt represents an event.

Visual Studio may also decorate these icons with other icons to indicate the way they are defined. For example, next to Finalize you’ll see a small key, which tells you the method is protected. The padlock icon tells us the item is private. It’s not really important to memorize all of these now, but Visual Basic 2005 is fairly consistent with its representations, so if you do learn them over time, they will help you understand what’s going on.

7.Select btnSayHello in the Class Name combo box. Now, drop down the Method Name combo box, as shown in Figure 6-4.

175