- •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
THE TEXTBOX CONTROL 245
The AcceptsTab property determines how the control reacts to the Tab key. Normally, the Tab key takes you to the next control in the tab order. In a TextBox control, however, you may wish for the Tab key to insert a Tab character in the text of the control instead; to do this, set this property to True. The default value of the AcceptsTab property is False, so that users can move to the next control with the Tab key. If you change the default value, users can still move to the next control in the tab order by pressing Ctrl+Tab. Notice that the AcceptsTab property has no effect on other controls. Users may have to press Ctrl+Tab to move to the next control while a TextBox control has the focus, but they can use the Tab key to move from any other control to the next one.
MaxLength
This property determines the number of characters the TextBox control will accept. Its default value is 32,767, which was the maximum number of characters the VB6 version of the control could hold. Set this property to zero, so that the text can have any length, up to the control’s capacity limit—
2 GB, or 2,147,483,647 characters to be exact. To restrict the number of characters the user can type, set the value of this property accordingly.
Note The MaxLength property of the TextBox control is often set to a specific value in data-entry applications. This prevents users from entering more characters than can be stored in a database field.
A TextBox control with its MaxLength property set to 0, its MultiLine property set to True, and its ScrollBars property set to Vertical is, on its own, a functional text editor. Place a TextBox control with these settings on a form, run the application, and check out the following:
Enter text and manipulate it with the usual editing keys, such as Delete, Insert, Home, and End.
Select multiple characters with the mouse or the arrow keys while holding down the Shift key.
Move segments of text around with Copy (Ctrl+C), Cut (Ctrl+X), and Paste (Ctrl+V) operations.
Exchange data with other applications through the Clipboard.
You can do all this without a single line of code! Shortly you’ll see what you can do with the TextBox control if you add some code to your application, but first, let’s look at a few more properties of TextBox control.
Text-Manipulation Properties
Most of the properties for manipulating text in a TextBox control are available at runtime only. This section presents a breakdown of each property.
Text
The most important property of the TextBox control is the Text property, which holds the control’s text. This property is also available at design time so that you can assign some initial text to the control. Notice that there are two methods of setting the Text property at design time. For single-line TextBox controls, set the Text property to a short string, as usual. For multiline TextBox controls, open the Lines
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
246 Chapter 6 BASIC WINDOWS CONTROLS
property and enter the text on the String Collection Editor window, which will appear. When you’re done, click OK to close the window. Each line you enter on the String Collection Editor window is a paragraph. Depending on the width of the control, this paragraph may be broken into multiple lines.
At runtime, use the Text property to extract the text entered by the user or to replace the existing text by assigning a new value to the property. The Text property is a string and can be used as argument with the usual string-manipulation functions of Visual Basic. It also supports all the members of the String class. The following expression returns the number of characters in the TextBox1 control:
Dim strLen As Integer
strLen = TextBox1.Text.Length
VB6 programmers are accustomed to calling the Len() function, which does the same:
strLen = Len(TextBox1.Text)
To clear the control, you can set its Text property to a blank string:
TextBox1.Text = “”
or call the control’s Clear method:
TextBox1.Clear
The IndexOf method of the String class will locate a string within the control’s text. The following statement returns the location of the first occurrence of the string “Visual” in the text:
Dim location As Integer
location = TextBox1.Text.IndexOf(“Visual”)
You can also use the InStr() function of VB:
location = Instr(TextBox1.Text, “Visual”)
The InStr() function allows you to specify whether the search will be case-sensitive or not, while the IndexOf method doesn’t. For more information on locating strings in a TextBox control, see the later section “VB.NET at Work: The TextPad Project,” where we’ll build a text editor with search and replace capabilities.
To store the control’s contents in a file, use a statement such as
StrWriter.Write(TextBox1.Text)
Similarly, you can read the contents of a text file into a TextBox control with a statement such as
TextBox1.Text = StrReader.ReadToEnd
where StrReader and StrWriter are two properly declared StreamReader and StreamWriter object variables. You will find out how to read from and write to files in Chapter 13, but you will also find the code for saving the text to a disk file (and reading text from a disk file as well) in the TextPad sample project, later in this chapter.
To locate all instances of a string in the text, use a loop like the one in Listing 6.1. This loop locates successive instances of the string “basic” and then continues searching from the character following the previous instance of the word in the text. To locate the last instance of a string in the text, use the LastIndexOf method. You can write a loop similar to the one of Listing 6.1 that scans the text backwards.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
THE TEXTBOX CONTROL 247
Listing 6.1: Locating a String in a TextBox
Dim startIndex = -1
startIndex = TextBox1.Text.IndexOf(“basic”, startIndex + 1) While startIndex > 0
Console.WriteLine(“String found at “ & startIndex) startIndex = TextBox1.Text.IndexOf(“basic”, startIndex + 1)
End While
To test Listing 6.1, place a multiline TextBox and a Button control on a form, then enter the statements of the listing in the button’s Click event handler. Run the application and enter some text on the TextBox control. Make sure the text contains the word “basic” or change the code to locate another word, and click the button. Notice that the IndexOf method performs a case-sensitive search.
Use the Replace method to replace a string with another within the line, the Split method to split the line into smaller components (like words), and any other method exposed by the String class. The following statement appends a string to the existing text on the control:
TextBox1.Text = TextBox1.Text & newString
This statement has appeared in just about any application that manipulated text with the TextBox control. It was an inefficient method to append text to the control, especially if the control contained a lot of text already. The problem with this statement isn’t obvious when you’re dealing with small text chunks. As the amount of text on the control increases, however, this statement takes longer to execute.
Now, you can use the AppendText method to append strings to the control, which is far more efficient that manipulating the Text property directly. To append a string to a TextBox control, use the following statement:
TextBox1.AppendText(newString)
The AppendText method appends the specified text to the control “as is,” without any line breaks between successive calls. If you want to append individual paragraphs to the control’s text, you must insert the line breaks explicitly, with a statement like the following:
TextBox1.AppendText(newString) & vbCrLf
vbCrLf is a VB constant that corresponds to the carriage return/new line characters.
ReadOnly, Locked
If you want to display text on a TextBox control but prevent users from editing it (an agreement or a contract they must read, software installation instructions, and so on), you can set the ReadOnly property to True. When ReadOnly is set to True, you can put text on the control from within your code, and users can view it, yet they can’t edit it.
To prevent the editing of the TextBox control with VB6, you had to set the Locked property to True. Oddly, the Locked property is also supported, but now it has a very different function. The Locked property of VB.NET locks the control at design time (so that you won’t move it or change its properties by mistake as you design the form).
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
248 Chapter 6 BASIC WINDOWS CONTROLS
Lines
In addition to the Text property, you can access the text on the control with the Lines property. Unlike the Text property, however, the Lines property is read-only: you can’t set the control’s text by assigning strings to the Lines array. Lines is a string array where each element holds a line of text. The first line of the text is stored in the element Lines(0), the second line of text is stored in the element Lines(1), and so on. You can iterate through the text lines with a loop like the following:
Dim iLine As Integer
For iLine = 0 To TextBox1.Lines.GetUpperBound(0)– 1
{ process string TextBox1.Lines(iLine) }
Next
You must replace the line in brackets with the appropriate code, of course. Because the Lines property is an array, it supports the GetUpperBound method, which returns the index of the last element in the array. Each element of the Lines array is a string, and you can call any of the String class’s methods to manipulate it. You can search for a string within the current line with the IndexOf and LastIndexOf methods, retrieve the line’s length with the Length property, and so on— just keep in mind that you can’t alter the text on the control by editing the Lines array. The String class is discussed in detail in Chapter 12. Alternatively, you can store the current line to a string variable and manipulate it with the usual string-manipulation functions of VB:
Dim myString As String
myString = TextBox1.Lines(iLine)
PasswordChar
Available at design time, this property turns the characters typed into any character you specify. If you don’t want to display the actual characters typed by the user (when entering a password, for instance), use this property to define the character to appear in place of each character the user types.
The default value of this property is an empty string, which tells the control to display the characters as entered. If you set this value to an asterisk (*), for example, the user sees an asterisk in the place of every character typed. This property doesn’t affect the control’s Text property, which contains the actual characters. If a text box’s PasswordChar property is set to any character, the user can’t even copy or cut the text. Any text that’s pasted on the control will appear as a sequence of whatever character has been specified with PasswordChar.
Text-Selection Properties
The TextBox control provides three properties for manipulating the text selected by the user: SelectedText, SelectionStart, and SelectionLength. For example, the user can select a range of text with a click-and-drag operation, and the selected text will appear in reverse color. You can access the selected text from within your code with the SelectedText property, and its location in the control’s text with the SelectionStart and SelectionLength properties.
SelectedText
This property returns the selected text, enabling you to manipulate the current selection from within your code. For example, you can replace the selection by assigning a new value to the
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
THE TEXTBOX CONTROL 249
SelectedText property. To convert the selected text to uppercase, use the ToUpper method of the String class:
TextBox1.SelectedText = TextBox1.SelectedText.ToUpper
or use the UCase() function of VB6:
TextBox1.SelectedText = UCase(TextBox1.SelectedText)
To delete the current selection, assign an empty string to the SelectedText property:
TextBox1.SelectedText = “”
SelectionStart, SelectionLength
The SelectionStart property returns or sets the position of the first character of the selected text in the control’s text, somewhat like placing the cursor at a specific location in the text and selecting text by dragging the mouse. The SelectionLength property returns or sets the length of the selected text. The most common use of these two properties is to extract the user’s selection or to select a piece of text from within the application. You’ll use these two properties to implement search and replace operations for a simple text editor.
Suppose the user is seeking the word “Visual” in the control’s text. The IndexOf method will locate the string, but it won’t select it. The found string may even be outside the visible area of the control. You can add a few more lines of code to select the word in the text and highlight it so that the user will spot it instantly:
Dim seekString As String Dim textStart As Integer seekString = “Visual”
textStart = TextBox1.Text.IndexOf(seekString) If textStart > 0 Then
TextBox1.SelectionStart = selStart – 1 TextBox1.SelectionLength = seekString.Length
End If TextBox1.ScrollToCaret()
These lines locate the string “Visual” (or any user-supplied string stored in the seekString variable) in the text and select it by setting the SelectionStart and SelectionLength properties of the TextBox control. The index of the first character on the control is zero, so we must subtract one from the location returned by the IndexOf method. Moreover, if the string is outside the visible area of the control, the user must scroll the text to bring the selection into view. The TextBox control provides the ScrollToCaret method, which brings the section of the text with the cursor into view.
The few lines of code shown above form the core of a text editor’s Search command. Replacing the current selection with another string is as simple as assigning a new value to the SelectedText property, and this technique provides you with an easy implementation of a find-and-replace operation. Designing a Find and Replace dialog box will take more effort than implementing the find-and-replace logic!
Tip The SelectionStart and SelectionLength properties always have a value even if no text has been selected. In this case, SelectionLength is 1, and SelectionStart is the current location of the pointer in the text. If you want to insert some text at the pointer’s location, simply assign it to the SelectedText property.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |