- •Using Your Sybex Electronic Book
- •Acknowledgments
- •Contents at a Glance
- •Introduction
- •Who Should Read This Book?
- •How About the Advanced Topics?
- •The Structure of the Book
- •How to Reach the Author
- •The Integrated Development Environment
- •The Start Page
- •Project Types
- •Your First VB Application
- •Making the Application More Robust
- •Making the Application More User-Friendly
- •The IDE Components
- •The IDE Menu
- •The Toolbox Window
- •The Solution Explorer
- •The Properties Window
- •The Output Window
- •The Command Window
- •The Task List Window
- •Environment Options
- •A Few Common Properties
- •A Few Common Events
- •A Few Common Methods
- •Building a Console Application
- •Summary
- •Building a Loan Calculator
- •How the Loan Application Works
- •Designing the User Interface
- •Programming the Loan Application
- •Validating the Data
- •Building a Math Calculator
- •Designing the User Interface
- •Programming the MathCalculator App
- •Adding More Features
- •Exception Handling
- •Taking the LoanCalculator to the Web
- •Working with Multiple Forms
- •Working with Multiple Projects
- •Executable Files
- •Distributing an Application
- •VB.NET at Work: Creating a Windows Installer
- •Finishing the Windows Installer
- •Running the Windows Installer
- •Verifying the Installation
- •Summary
- •Variables
- •Declaring Variables
- •Types of Variables
- •Converting Variable Types
- •User-Defined Data Types
- •Examining Variable Types
- •Why Declare Variables?
- •A Variable’s Scope
- •The Lifetime of a Variable
- •Constants
- •Arrays
- •Declaring Arrays
- •Initializing Arrays
- •Array Limits
- •Multidimensional Arrays
- •Dynamic Arrays
- •Arrays of Arrays
- •Variables as Objects
- •So, What’s an Object?
- •Formatting Numbers
- •Formatting Dates
- •Flow-Control Statements
- •Test Structures
- •Loop Structures
- •Nested Control Structures
- •The Exit Statement
- •Summary
- •Modular Coding
- •Subroutines
- •Functions
- •Arguments
- •Argument-Passing Mechanisms
- •Event-Handler Arguments
- •Passing an Unknown Number of Arguments
- •Named Arguments
- •More Types of Function Return Values
- •Overloading Functions
- •Summary
- •The Appearance of Forms
- •Properties of the Form Control
- •Placing Controls on Forms
- •Setting the TabOrder
- •VB.NET at Work: The Contacts Project
- •Anchoring and Docking
- •Loading and Showing Forms
- •The Startup Form
- •Controlling One Form from within Another
- •Forms vs. Dialog Boxes
- •VB.NET at Work: The MultipleForms Project
- •Designing Menus
- •The Menu Editor
- •Manipulating Menus at Runtime
- •Building Dynamic Forms at Runtime
- •The Form.Controls Collection
- •VB.NET at Work: The DynamicForm Project
- •Creating Event Handlers at Runtime
- •Summary
- •The TextBox Control
- •Basic Properties
- •Text-Manipulation Properties
- •Text-Selection Properties
- •Text-Selection Methods
- •Undoing Edits
- •VB.NET at Work: The TextPad Project
- •Capturing Keystrokes
- •The ListBox, CheckedListBox, and ComboBox Controls
- •Basic Properties
- •The Items Collection
- •VB.NET at Work: The ListDemo Project
- •Searching
- •The ComboBox Control
- •The ScrollBar and TrackBar Controls
- •The ScrollBar Control
- •The TrackBar Control
- •Summary
- •The Common Dialog Controls
- •Using the Common Dialog Controls
- •The Color Dialog Box
- •The Font Dialog Box
- •The Open and Save As Dialog Boxes
- •The Print Dialog Box
- •The RichTextBox Control
- •The RTF Language
- •Methods
- •Advanced Editing Features
- •Cutting and Pasting
- •Searching in a RichTextBox Control
- •Formatting URLs
- •VB.NET at Work: The RTFPad Project
- •Summary
- •What Is a Class?
- •Building the Minimal Class
- •Adding Code to the Minimal Class
- •Property Procedures
- •Customizing Default Members
- •Custom Enumerations
- •Using the SimpleClass in Other Projects
- •Firing Events
- •Shared Properties
- •Parsing a Filename String
- •Reusing the StringTools Class
- •Encapsulation and Abstraction
- •Inheritance
- •Inheriting Existing Classes
- •Polymorphism
- •The Shape Class
- •Object Constructors and Destructors
- •Instance and Shared Methods
- •Who Can Inherit What?
- •Parent Class Keywords
- •Derived Class Keyword
- •Parent Class Member Keywords
- •Derived Class Member Keyword
- •MyBase and MyClass
- •Summary
- •On Designing Windows Controls
- •Enhancing Existing Controls
- •Building the FocusedTextBox Control
- •Building Compound Controls
- •VB.NET at Work: The ColorEdit Control
- •VB.NET at Work: The Label3D Control
- •Raising Events
- •Using the Custom Control in Other Projects
- •VB.NET at Work: The Alarm Control
- •Designing Irregularly Shaped Controls
- •Designing Owner-Drawn Menus
- •Designing Owner-Drawn ListBox Controls
- •Using ActiveX Controls
- •Summary
- •Programming Word
- •Objects That Represent Text
- •The Documents Collection and the Document Object
- •Spell-Checking Documents
- •Programming Excel
- •The Worksheets Collection and the Worksheet Object
- •The Range Object
- •Using Excel as a Math Parser
- •Programming Outlook
- •Retrieving Information
- •Recursive Scanning of the Contacts Folder
- •Summary
- •Advanced Array Topics
- •Sorting Arrays
- •Searching Arrays
- •Other Array Operations
- •Array Limitations
- •The ArrayList Collection
- •Creating an ArrayList
- •Adding and Removing Items
- •The HashTable Collection
- •VB.NET at Work: The WordFrequencies Project
- •The SortedList Class
- •The IEnumerator and IComparer Interfaces
- •Enumerating Collections
- •Custom Sorting
- •Custom Sorting of a SortedList
- •The Serialization Class
- •Serializing Individual Objects
- •Serializing a Collection
- •Deserializing Objects
- •Summary
- •Handling Strings and Characters
- •The Char Class
- •The String Class
- •The StringBuilder Class
- •VB.NET at Work: The StringReversal Project
- •VB.NET at Work: The CountWords Project
- •Handling Dates
- •The DateTime Class
- •The TimeSpan Class
- •VB.NET at Work: Timing Operations
- •Summary
- •Accessing Folders and Files
- •The Directory Class
- •The File Class
- •The DirectoryInfo Class
- •The FileInfo Class
- •The Path Class
- •VB.NET at Work: The CustomExplorer Project
- •Accessing Files
- •The FileStream Object
- •The StreamWriter Object
- •The StreamReader Object
- •Sending Data to a File
- •The BinaryWriter Object
- •The BinaryReader Object
- •VB.NET at Work: The RecordSave Project
- •The FileSystemWatcher Component
- •Properties
- •Events
- •VB.NET at Work: The FileSystemWatcher Project
- •Summary
- •Displaying Images
- •The Image Object
- •Exchanging Images through the Clipboard
- •Drawing with GDI+
- •The Basic Drawing Objects
- •Drawing Shapes
- •Drawing Methods
- •Gradients
- •Coordinate Transformations
- •Specifying Transformations
- •VB.NET at Work: Plotting Functions
- •Bitmaps
- •Specifying Colors
- •Defining Colors
- •Processing Bitmaps
- •Summary
- •The Printing Objects
- •PrintDocument
- •PrintDialog
- •PageSetupDialog
- •PrintPreviewDialog
- •PrintPreviewControl
- •Printer and Page Properties
- •Page Geometry
- •Printing Examples
- •Printing Tabular Data
- •Printing Plain Text
- •Printing Bitmaps
- •Using the PrintPreviewControl
- •Summary
- •Examining the Advanced Controls
- •How Tree Structures Work
- •The ImageList Control
- •The TreeView Control
- •Adding New Items at Design Time
- •Adding New Items at Runtime
- •Assigning Images to Nodes
- •Scanning the TreeView Control
- •The ListView Control
- •The Columns Collection
- •The ListItem Object
- •The Items Collection
- •The SubItems Collection
- •Summary
- •Types of Errors
- •Design-Time Errors
- •Runtime Errors
- •Logic Errors
- •Exceptions and Structured Exception Handling
- •Studying an Exception
- •Getting a Handle on this Exception
- •Finally (!)
- •Customizing Exception Handling
- •Throwing Your Own Exceptions
- •Debugging
- •Breakpoints
- •Stepping Through
- •The Local and Watch Windows
- •Summary
- •Basic Concepts
- •Recursion in Real Life
- •A Simple Example
- •Recursion by Mistake
- •Scanning Folders Recursively
- •Describing a Recursive Procedure
- •Translating the Description to Code
- •The Stack Mechanism
- •Stack Defined
- •Recursive Programming and the Stack
- •Passing Arguments through the Stack
- •Special Issues in Recursive Programming
- •Knowing When to Use Recursive Programming
- •Summary
- •MDI Applications: The Basics
- •Building an MDI Application
- •Built-In Capabilities of MDI Applications
- •Accessing Child Forms
- •Ending an MDI Application
- •A Scrollable PictureBox
- •Summary
- •What Is a Database?
- •Relational Databases
- •Exploring the Northwind Database
- •Exploring the Pubs Database
- •Understanding Relations
- •The Server Explorer
- •Working with Tables
- •Relationships, Indices, and Constraints
- •Structured Query Language
- •Executing SQL Statements
- •Selection Queries
- •Calculated Fields
- •SQL Joins
- •Action Queries
- •The Query Builder
- •The Query Builder Interface
- •SQL at Work: Calculating Sums
- •SQL at Work: Counting Rows
- •Limiting the Selection
- •Parameterized Queries
- •Calculated Columns
- •Specifying Left, Right, and Inner Joins
- •Stored Procedures
- •Summary
- •How About XML?
- •Creating a DataSet
- •The DataGrid Control
- •Data Binding
- •VB.NET at Work: The ViewEditCustomers Project
- •Binding Complex Controls
- •Programming the DataAdapter Object
- •The Command Objects
- •The Command and DataReader Objects
- •VB.NET at Work: The DataReader Project
- •VB.NET at Work: The StoredProcedure Project
- •Summary
- •The Structure of a DataSet
- •Navigating the Tables of a DataSet
- •Updating DataSets
- •The DataForm Wizard
- •Handling Identity Fields
- •Transactions
- •Performing Update Operations
- •Updating Tables Manually
- •Building and Using Custom DataSets
- •Summary
- •An HTML Primer
- •HTML Code Elements
- •Server-Client Interaction
- •The Structure of HTML Documents
- •URLs and Hyperlinks
- •The Basic HTML Tags
- •Inserting Graphics
- •Tables
- •Forms and Controls
- •Processing Requests on the Server
- •Building a Web Application
- •Interacting with a Web Application
- •Maintaining State
- •The Web Controls
- •The ASP.NET Objects
- •The Page Object
- •The Response Object
- •The Request Object
- •The Server Object
- •Using Cookies
- •Handling Multiple Forms in Web Applications
- •Summary
- •The Data-Bound Web Controls
- •Simple Data Binding
- •Binding to DataSets
- •Is It a Grid, or a Table?
- •Getting Orders on the Web
- •The Forms of the ProductSearch Application
- •Paging Large DataSets
- •Customizing the Appearance of the DataGrid Control
- •Programming the Select Button
- •Summary
- •How to Serve the Web
- •Building a Web Service
- •Consuming the Web Service
- •Maintaining State in Web Services
- •A Data-Driven Web Service
- •Consuming the Products Web Service in VB
- •Summary
122 Chapter 3 VISUAL BASIC: THE LANGUAGE
Arrays
A standard structure for storing data in any programming language is the array. Whereas individual variables can hold single entities, such as one number, one date, or one string, arrays can hold sets of data of the same type (a set of numbers, a series of dates, and so on). An array has a name, as does a variable, and the values stored in it can be accessed by an index.
For example, you could use the variable Salary to store a person’s salary:
Salary = 34000
But what if you wanted to store the salaries of 16 employees? You could either declare 16 vari- ables—Salary1, Salary2, up to Salary16—or you could declare an array with 16 elements. An array is similar to a variable: it has a name and multiple values. Each value is identified by an index (an integer value) that follows the array’s name in parentheses. Each different value is an element of the array. If the array Salaries holds the salaries of 16 employees, the element Salaries(0) holds the salary of the first employee, the element Salaries(1) holds the salary of the second employee, and so on up
the element Salaries(15).
VB6 VB.NET
The indexing of arrays in VB.NET starts at zero, and you can’t change this behavior, because the Option Base statement, which allowed you to specify whether the indexing of the array would start at 0 or 1, is no longer supported by VB.NET. Whether you like it or not, your arrays must start at index zero. If you don’t feel comfortable with the notion of zero being the first element, you can increase the dimensions of your arrays by one and ignore the zeroth element.
In VB6 you could specify not only the dimensions of an array but also the index of the very first element, with a declaration like
Dim myArray(101 To 999) As Integer
This notation is not valid in VB.NET.
Declaring Arrays
Unlike simple variables, arrays must be declared with the Dim (or Public, or Private) statement followed by the name of the array and the index of the last element in the array in parentheses—for example,
Dim Salaries(15) As Integer
Note Actually, there are occasions when you need not specify the exact dimensions of an array, as you’ll see shortly.
As I said before, Salaries is the name of an array that holds 16 values (the salaries of the 16 employees), with indices ranging from 0 to 15. Salaries(0) is the first person’s salary, Salaries(1) the second person’s salary, and so on. All you have to do is remember who corresponds to each
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
ARRAYS 123
salary, but even this data can be handled by another array. To do this, you’d declare another array of 16 elements as follows:
Dim Names(15) As String
and then assign values to the elements of both arrays:
Names(0) = “Joe Doe” Salaries(0) = 34000 Names(1) = “Beth York” Salaries(1) = 62000
...
Names(15) = “Peter Smack” Salaries(15) = 10300
This structure is more compact and more convenient than having to hard-code the names of employees and their salaries in variables.
All elements in an array have the same data type. Of course, when the data type is Object, the individual elements can contain different kinds of data (objects, strings, numbers, and so on).
Arrays, like variables, are not limited to the basic data types. You can declare arrays that hold any type of data, including objects. The following array holds colors, which can be used later in the code as arguments to the various functions that draw shapes:
Dim colors(2) As Color colors(0) = Color.BurlyWood colors(1) = Color.AliceBlue colors(2) = Color.Sienna
The Color object represents colors, and among the properties it exposes are the names of the colors it recognizes. The Color object recognizes 128 color names (as opposed to the 16 color names of VB6).
As a better technique to store names and salaries together in an array, create a Structure and then declare an array of this type. The following structure holds names and salaries:
Structure Employee
Dim Name As String
Dim Salary As Single
End Structure
Insert this declaration in a form’s code file, outside any procedure. Then create an array of the Employee type:
Dim Emps(15) As Employee
Each elements in the Emps array exposes two fields, and you can assign values to them with statements like the following ones:
Emps(2).Name = “Beth York”
Emps(2).Salary = 62000
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
124 Chapter 3 VISUAL BASIC: THE LANGUAGE
The advantage of storing related pieces of information to a structure is that you can access all the items with a single index. The code is more compact, and you need not maintain multiple arrays. In Chapter 11, you’ll see how to store structures and other objects to collections like ArrayLists and HashTables.
Initializing Arrays
Just as you can initialize variables in the same line where you declare them, you can initialize arrays, too, with the following constructor:
Dim arrayname() As type = {entry0, entry1, … entryN}
Here’s an example that initializes an array of strings:
Dim names() As String = {“Joe Doe”, “Peter Smack”}
This statement is equivalent to the following statements, which declare an array with two elements and then set their values:
Dim names(1) As String names(0) = “Joe Doe” names(1) = “Peter Smack”
The number of elements in the curly brackets following the array’s declaration determines the dimensions of the array, and you can’t add new elements to the array without resizing it. If you need to resize the array in your code dynamically, you must use the ReDim statement, as described in the section “Dynamic Arrays,” later in this chapter. However, you can change the value of the existing elements at will, as you would with any other array. The following declaration initializes an array of Color objects in a single statement:
Dim Colors() As Color = {Color.BurlyWood, Color.AliceBlue, Color.Sienna, _
Color.Azure, Color.Fuchsia, Color.White}
Array Limits
The first element of an array has index 0. The number that appears in parentheses in the Dim statement is one less than the array’s total capacity and is the array’s upper limit (or upper bound).
The index of the last element of an array (its upper bound) is given by the function UBound(), which accepts as argument the array’s name. For the array
Dim myArray(19) As Integer
its upper bound is 19, and its capacity is 20 elements. The function UBound() is also exposed as a method of the Array object, and it’s the GetUpperBound method. It returns the same value as the UBound() function. The GetLowerBound method returns the index of the array’s first element, which is always zero anyway. As you will see, arrays can have multiple dimensions, so these two methods require that you specify the dimensions whose limits you want to read as arguments. For one-dimensional arrays, like the ones discussed in this section, this argument is zero. Multidimensional arrays are discussed later in this chapter.
Let’s say you need an array to store 20 names. Declare it with the following statement:
Dim names(19) As String
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
ARRAYS 125
The first element is names(0), and the last is names(19). If you execute the following statements, the values in bold will appear in the Output window:
Console.WriteLine(names.GetLowerBound(0))
0
Console.WriteLine(names.GetUpperBound(0))
19
To assign a value to the first and last element of the names array, use the following statements:
names(0) = “First entry” names(19) = “Last entry”
If you want to iterate through the array’s elements, use a loop like the following one:
Dim i As Integer, myArray(19) As Integer For i = 0 To myArray.GetUpperBound(0)
myArray(i) = i * 1000 Next
The actual number of elements in an array is given by the expression myArray.GetUpperBound(0) + 1. You can also use the array’s Length property to retrieve the count of elements. The following statement will print the number of elements in the array myArray on the Output window:
Console.WriteLine(myArray.Length)
Still confused with the zero indexing scheme, the count of elements, and the index of the last element in the array? It’s safe to make the array a little larger than it need be and ignore the first element. Just make sure you never use the zeroth elements in your code—don’t store a value in the element Array(0), and you can then ignore this element. To get 20 elements, declare an array with 21 elements as Dim myArray(20) As type and then ignore the first element.
Arrays are one of the most improved areas of VB.NET. For years, programmers invested endless hours to write routines for sorting and searching arrays. It took Microsoft years to get arrays right, but with VB.NET you can manipulate arrays with several methods and properties available through the Array class, which is described in detail in Chapter 11. In this chapter, you’ll learn the basics of declaring, populating, and accessing array elements, which is all you need to start using arrays in your code. The Array class will help you manipulate arrays in more elaborate ways.
Multidimensional Arrays
One-dimensional arrays, such as those presented so far, are good for storing long sequences of onedimensional data (such as names or temperatures). But how would you store a list of cities and their average temperatures in an array? Or names and scores, years and profits, or data with more than two dimensions, such as products, prices, and units in stock? In some situations you will want to store sequences of multidimensional data. You can store the same data more conveniently in an array of as many dimensions as needed. Figure 3.4 shows two one-dimensional arrays—one of them with city names, the other with temperatures. The name of the third city would be City(2), and its tempera-
ture would be Temperature(2).
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
126 Chapter 3 VISUAL BASIC: THE LANGUAGE
Figure 3.4
A two-dimensional array and the two equivalent onedimensional arrays
A two-dimensional array has two indices. The first identifies the row (the order of the city in the array), and the second identifies the column (city or temperature). To access the name and temperature of the third city in the two-dimensional array, use the following indices:
Temperatures(2, |
0) |
‘ |
the |
third |
city’s |
name |
Temperatures(2, |
1) |
‘ |
the |
third |
city’s |
average temperature |
The benefit of using multidimensional arrays is that they’re conceptually easier to manage. Suppose you’re writing a game and want to track the positions of certain pieces on a board. Each square on the board is identified by two numbers, its horizontal and vertical coordinates. The obvious structure for tracking the board’s squares is a two-dimensional array, in which the first index corresponds to the row number and the second corresponds to the column number. The array could be declared as follows:
Dim Board(9, 9) As Integer
When a piece is moved from the square on the first row and first column to the square on the third row and fifth column, you assign the value 0 to the element that corresponds to the initial position:
Board(0, 0) = 0
and you assign 1 to the square to which it was moved, to indicate the new state of the board:
Board(2, 4) = 1
To find out if a piece is on the top-left square, you’d use the following statement:
If Board(0, 0) = 1 Then
{piece found }
Else
{empty square } End If
This notation can be extended to more than two dimensions. The following statement creates an array with 1,000 elements (10 by 10 by 10):
Dim Matrix(9, 9, 9)
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
ARRAYS 127
You can think of a three-dimensional array as a cube made up of overlaid two-dimensional arrays, such as the one shown in Figure 3.5.
Figure 3.5
Pictorial representations of one-, two-, and three-dimen- sional arrays
It is possible to initialize a multidimensional array with a single statement, just as you do with a one-dimensional array. You must insert enough commas in the parentheses following the array name to indicate the array’s rank (the number of commas is one less than the actual dimensions). The following statements initialize a two-dimensional array and then print a couple of its elements:
Dim a(,) As Integer = {{10, 20, 30}, {11, 21, 31}, {12, 22, 32}}
Console.WriteLine(a(0, |
1)) |
‘ |
will |
20 |
|
Console.WriteLine(a(2, |
2)) |
‘ |
will |
32 |
You should break the line that initializes the dimensions of the array into multiple lines to make your code easier to read. Just insert the line-continuation character at the end of each continued line:
Dim a(,) As Integer = {{10, 20, 30}, _ {11, 21, 31}, _ {12, 22, 32}}
If the array has more than one dimension, you can find out the number of dimensions with the Array.Rank property. Let’s say you have declared an array for storing names as salaries with the following statements:
Dim Salaries(1,99) As Object
To find out the number of dimensions, use the statement:
Salaries.Rank
When using the Length property to find out the number of elements in a multidimensional array, you will get back the total number of elements in the array—2 × 100, for our example. To find out the number of elements in a specific dimension use the GetLength method, passing as argument a specific dimension. The following expression will return the number of elements in the first dimension of the array:
Console.WriteLine(Salaries.GetLength(0))
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |