- •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
Chapter 16
The TreeView and
ListView Controls
The last two Windows controls we’re going to explore in this chapter are among the more advanced ones, and they are certainly more difficult to program than the previous ones. These two controls, however, are the basic makings of unique user interfaces, as you’ll see in the examples. The TreeView and ListView controls implement two of the more advanced data structures (a topic that’s not terribly popular even among computer science students). These controls were designed to hide much of the complexity of the data structures they implement, and they do this very well. However, they are more difficult to use than the other controls.
The ImageList control is a simple control for storing images, which is used frequently with these two controls. In itself, the ImageList control is very simple to use, and I will show briefly how to use this control in conjunction with the other two controls, which are the main subject of this chapter.
I will start with a general discussion of the two controls to help you understand what they do and when to use them. A basic understanding of the data structures they implement is also required to use them efficiently in your applications. Then, I’ll discuss their members and demonstrate how to use the controls. If you find the examples too difficult to understand, you can always postpone the use of these controls in your applications. Some of the code I will present in this chapter can be used as is in many situations, so you should take a look at the examples and see if you can incorporate some of them in your applications. Unlike other controls, the TreeView and ListView controls can be considered advanced, which is why I haven’t discussed them in the first part of the book. They’re also excellent tools for designing elaborate Windows interfaces and I feel they deserve to be covered in detail.
Examining the Advanced Controls
In Chapter 5, you learned that the ListBox control is a simple control for storing objects. The items of a ListBox control can be sorted, but they have no particular structure. I’m sure most of you wish the ListBox control had more “features,” such as the means to store additional information along with each item and display them at will. For instance, a list with city and state names should be structured so that each city appears under the corresponding state name. In a ListBox control, you can indent some of the entries, but the control itself can’t impose or maintain any
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
742 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS
structure on its data. The answer to the shortcomings of the ListBox control can be found in the TreeView and ListView controls.
Figure 16.1 shows the TreeView and ListView controls used in tandem. What you see in Figure 16.1 is Windows Explorer, a utility for examining and navigating your hard disk’s structure. The left pane, where the folders are displayed, is a TreeView control. The folder names are displayed in a manner that reflects their structure on the hard disk. You can expand and contract certain branches and view only the segment(s) of the tree structure you’re interested in.
The right pane is a ListView control. The items on the ListView control can be displayed in four different ways (as large icons, as small icons, in a list, or in report form). These are the various views you can set through the View menu of Windows Explorer. Although most people prefer to look at the contents of the folders as icons, the most useful view is the Report view, which displays not only filenames but their attributes as well. In the Report view, the list can be sorted according to any of its columns, making it very easy for the user to locate any item based on various criteria (file type, size, creation date, and so on).
Figure 16.1
Windows Explorer is made up of a TreeView (left pane) and a ListView (right pane).
VB6 VB.NET
If you’ve programmed the TreeView control that came with VB6, you’re probably dependent on the Key property, which uniquely identified each node and allowed you to place new nodes under existing nodes by specifying the key of the parent node. The Key property is no longer supported. The Find method of the old version of the control, which located an item based on its key, is also gone. The new version of the control is strictly a tool for displaying data, and it provides all the functionality needed to interact with the user. You will miss some of the functionality of the old TreeView control that didn’t make it to the new control. On the positive side, the new control gives more control over the appearance of the items—you can set their font, background color, and so on. It also comes with a tool that allows you to add nodes at design time.
The new version of the control is in many respects different from the old version, and you’ll practically have to learn to program it like a new control.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
EXAMINING THE ADVANCED CONTROLS 743
How Tree Structures Work
The TreeView control implements a data structure known as a tree. A tree is the most appropriate structure for storing hierarchical information. The organizational chart of most companies is a tree structure. Every person reports to another person above them, all the way to the president or CEO. Figure 16.2 depicts a possible organization of continents, countries, and cities as a tree. (For brevity, I sometimes abstract a bit; “America” is treated as a single continent, and I’ve omitted Antarctica because is has no countries or cities.) Every city belongs to a country and every country to a continent. In the same way, every computer file belongs to a folder that may belong to an even bigger folder. You can’t draw large tree structures on paper, but it’s possible to create a similar structure in the computer’s memory without size limitations.
Figure 16.2
The world viewed as a tree
Each item in the tree of Figure 16.2 is called a node, and nodes can be nested to any level. Oddly, the top node is the root of the tree and the subordinate nodes are called child nodes. If you try to visualize this structure as a real tree, think of it as an upside-down tree with the branches emerging from the root.
To locate a city, you must start at the root node and select the continent to which the city belongs. Then, you must find the country (in the selected continent) to which the city belongs. Finally, you can find the city you’re looking for. If it’s not under the appropriate country node, then it doesn’t exist. You also can traverse a tree in the opposite direction. There may an identically named city in another country, but this isn’t the one you’re looking for; it’s just a synonym.
Note The TreeView control doesn’t require that the items be unique. You can actually have identically named nodes in the same branch—as unlikely as this may be for a real application. The nodes are strings and they can be anything. There’s no property that makes a node unique in the tree structure, or even in its own branch.
You can start with a city and find its country. The country node is the city node’s parent node. Notice that there is only one route from child nodes to their parent nodes, which means you can instantly locate the country or continent of a city. The same data shown in Figure 16.2 is shown in Figure 16.3 on a TreeView control. Only the nodes we’re interested in are expanded. The plus sign indicates that the corresponding node contains child nodes. To view them, click the button with the plus sign to expand the node.
The tree structure is ideal for data with parent-child relations (relations that can be described as “belongs to” or “owns”). The continents-countries-cities data is a typical example. The folder structure on a hard disk is another typical example. Any given folder is the child of another folder or the
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
744 Chapter 16 THE TREEVIEW AND LISTVIEW CONTROLS
root folder. If you need a method to traverse the folder structure of your hard disk quickly and conveniently, you must store the folders in a TreeView control. This is exactly what happens when you use Windows Explorer to navigate your hard disk. Of course, there are other ways to navigate your hard disk (you can do the same with an Open dialog box), but the TreeView control helps you visualize the structure of the entire disk. With the Open dialog box, you can view only one segment of the disk, namely, the current folder.
Figure 16.3
The tree of Figure 16.2 implemented with a TreeView control
Many programs are actually based on tree structures. Computerized board games use a tree structure to store all possible positions. Every time the computer has to make a move, it locates the board’s status on the tree and selects the “best” next move. For instance, in tic-tac-toe, the tree structure that represents the moves in the game has nine nodes on the first level, which correspond to all the possible positions for the first token on the board (the X or O mark). Under each possible initial position, there are eight nodes, which correspond to all the possible positions of the second token on the board (one of the nine positions is already taken). On the second level, there are 9 × 8, or 72 nodes. On the third level, there are seven nodes under each node that correspond to all the possible positions of the third token, a total of 72 × 7, or 504 nodes, and so on. In each node, you can store a value that indicates whether the corresponding move is good or bad. When the computer has to make a move, it traverses the tree to locate the current status of the board, and then it makes a good move.
Of course, tic-tac-toe is a very simple game. In principle, you could design a chess-playing game using a tree. This tree, however, would grow so large so quickly that it couldn’t be stored in any reasonable amount of memory. Moreover, scanning the nodes of this enormous tree would be a slow process. If you also consider that chess moves aren’t just good or bad (there are better and not-so- good moves), and you must look ahead many moves to decide which move is the best for the current status of the board, you’ll realize that this ad hoc approach is totally impractical. Practically speaking, such a program requires either infinite resources or infinite time. That’s why the chess-playing algorithms use heuristic approaches, which store every recorded chess game in a database and consult this database to pick the best next move.
Maintaining a tree structure is a fundamental operation in software design; computer science students spend a good deal of their time implementing tree structures. Even the efficient implementation of a tree structure is a research subject. Fortunately, with Visual Basic you don’t have to implement tree structures on your own. The TreeView control is a mechanism for storing hierarchically structured data on a control with a visible interface. The TreeView control hides (or encapsulates, in object-oriented terminology) the details of the implementation and allows you
to set up tree structures with a few lines of code. In short, all the gain without the pain (almost).
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
EXAMINING THE ADVANCED CONTROLS 745
You may find this too good to be true, but if you’ve ever had to implement tree structures, you’ll appreciate the simplicity of the TreeView control.
Programming the TreeView control is not as simple as programming other controls, but keep in mind that the TreeView control implements a complicated data structure. It’s far simpler to program the TreeView control than to implement tree structures from scratch. There’s not much you can do about efficiency, and unless you’re developing highly specialized applications that rely on tree structures, the TreeView control is your best bet.
The ListView control implements a simpler structure, known as a list. A list’s items aren’t structured in a hierarchy. They are all on the same level and can be traversed serially, one after the other. You can also think of the list as an array, but the list offers more features. A list item can have subitems and can be sorted in many ways. For example, you can set up a list of customer names (the list’s items) and assign a number of subitems to each customer, like a contact, an address, a phone number, and so on. Or you can set up a list of files with their attributes as subitems. Figure 16.4 shows a Windows folder mapped on a ListView control. Each file is an item, and its attributes are the subitems. As you already know, you can sort this list by filename, size, file type, and so on. All you have to do is click the header of the corresponding column. You can also display the list of files in different views: as icons, as a list of filenames only, or as a report (the view shown in Figure 16.4).
Figure 16.4
A folder’s files displayed in a TreeView control (Report view)
The ListView control is a glorified ListBox control. If all you need is a control to store sorted objects, use a ListBox control. If you want more features, like storing multiple items per row, sorting them in different ways, or locating them based on any subitem’s value, then you must consider the ListView control. It’s simpler to program than the TreeView control but still more involved than the simple ListBox control.
To program the TreeView and ListView controls, you must understand the concept of collections. You can’t simply add items to these controls with the Add method as you would do with the ListBox control. Each level of nodes in the TreeView control is a collection. Each item in this collection represents a node, which may have child nodes. Each node’s child nodes form another collection. Each item
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |