- •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
390 Chapter 8 BUILDING CUSTOM CLASSES
You can open the Matrix project on the CD, examine the code, and add more features to the Matrix class, starting with a method that inverts matrices (a complicated algorithm that I have not implemented in the sample project). You will notice that I’ve implemented the class in the form’s file. After adding all the functionality you need to the class, you can copy the class’s code into another project and create a class to use with any of your projects.
Summary
In this chapter, you learned the mechanics of building custom classes, and you were exposed to the main concepts of object-oriented programming. Inheritance and polymorphism are the two most powerful features introduced into the Visual Basic programming language, which bring it to the same level as the other two languages of Visual Studio.
The reason for using classes is code reuse. Classes are robust and not susceptible to changes. If another developer needs to extend your class, adding more members or overwriting existing members, they can do so by inheriting the functionality of your class. The existing applications will work with the old class, while newer applications can use the new one. You can also edit your class’s code without breaking any existing code. Just make sure you don’t change the interface of a class.
Now that you understand what classes are, how they work, and what they can do for you, we’re going to explore some useful classes that come with the .NET Framework. Of the numerous Framework classes, I’ve selected a few that most developers will be using on a daily basis and will discuss them at length in the following chapters. There are many more classes than I even list in this book. Once you familiarize yourself with the most basic ones, you will find it easier to discover the functionality of the other classes, or locate in the documentation the one that exposes the functionality you need.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
Chapter 9
Building Custom
Windows Controls
Since version 5 of the language, VB has made it very simple to build custom controls, and it’s gotten even better with VB.NET. In addition to a host of controls that come with VB.NET and the capability to use ActiveX controls with .NET, you can also easily create your own custom
.NET controls.
The design of custom Windows controls has been one of the best implemented features of the language. Creating custom controls with VB.NET is even simpler, mostly because of the functionality added to the UserControl object.
Now, who should be developing custom Windows controls and why? If you come up with an interesting utility that can be used from within several applications, why not package it as a custom control and reuse it in your projects? You can also pass it to other developers and make sure that your application has a consistent look. For example, you might develop a custom control for designing reports or displaying lists of customers. Every form that uses this functionality should be implemented around this control. Users will learn to use the application faster, and the custom control will help you maintain a consistent look throughout the application.
In this chapter, you will learn how to design custom Windows controls for .NET. We’ll start by designing a new control that inherits an existing control and adds some extra functionality. Just as in the previous chapter we created a custom ArrayList that incorporated all the functionality of the original ArrayList and added some methods to it, we’ll do the same with the TextBox control. Then you’ll see how to build custom controls that combine multiple .NET controls. These controls are called compound controls, and they’re like regular forms with built-in functionality. The ComboBox control, for example, is a compound control made up of a TextBox (its edit area), a ListBox, and a Button that expands the list. Compound controls ride on the functionality of their constituent controls, and you can add specific functionality through custom properties and methods. Finally, you’ll learn how to build user-drawn controls. A user-drawn control is an empty surface, and you’re responsible for drawing the control’s interface (and updating it in response to external events).
We’ll also discuss a few interesting, out of the ordinary, topics, like how to take control of the drawing process of the MenuItem object and create menus with graphics. You’ll also learn how easy it is to build nonrectangular controls.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
392 Chapter 9 BUILDING CUSTOM WINDOWS CONTROLS
On Designing Windows Controls
Before I get to the details of how to build custom controls, I want to show you how they relate to other types of projects. I’m going to discuss briefly the similarities and differences among Windows controls, classes, and standard projects. This information will help you get the big picture and put together the pieces of the following sections.
A standard application consists of a main form and several (optional) auxiliary forms. The auxiliary forms support the main form, as they usually accept user data that are processed by the code in the main form. You can think of a custom control as a form and think of its Properties window as the auxiliary form. An application interacts with the user through its interface. The developer decides how the forms interact with the user, and the user has to follow these rules. Something similar happens with custom controls. The custom control provides a well-defined interface, which consists of properties and methods. This is the only way to manipulate the control. Just as users of your applications don’t have access to the source code and can’t modify the application, developers can’t see the control’s source code and must access a Windows control through the interface exposed by the control. When you develop a custom control, in turn, you can use any of the controls on the Toolbox. Once an instance of the control is on the form, you can manipulate it through its properties and methods and you never get to see its code.
In Chapter 8, you learned how to implement interfaces consisting of properties and methods and how to raise events from within a class. This is how you build the interface of a custom Windows control. You implement properties as Property procedures, and you implement methods as Public procedures. Whereas a class may provide a few properties and any number of methods, a control must provide a large number of properties. A developer who places your custom control on a form expects to see the properties that are common to all the controls that are visible at runtime (properties to set the control’s dimensions, its color, the text font, the Index and Tag properties, and so on). Fortunately, many of the standard properties are exposed automatically. The developer also expects to be able to program all the common events, such as the mouse and keyboard events, as well as some events that are unique to the custom control.
The design of a Windows control is similar to the design of a form. You place controls on a Form-like object, called UserControl, which is the control’s surface. It provides nearly all the methods of a standard form, and you can adjust its appearance with the drawing methods. In other words, you can use familiar programming techniques to draw a custom control, or you can use existing controls to build a custom control.
The forms of an application are the windows you see on the Desktop when the application is executed. When you design the application, you can rearrange the controls on a form and program how they react to user actions. Windows controls are also windows, only they can’t exist on their own and can’t be placed on the Desktop. They must be placed on forms.
The major difference between applications and custom controls is that custom controls can exist in two runtime modes. When the developer places a control on a form, the control is actually running. When you set a control’s property through the Properties window, something happens to the control; its appearance changes, or the control rejects the changes. This means that the code of the custom control is executing, even though the project on which the control is used is in design mode. When the developer starts the application, the custom control is already running. However, the control must be able to distinguish when the project is in design or execution mode and behave accordingly. Here’s the first property of the UserControl object you will be using quite frequently in your code: the DesignMode property. When the control is positioned on a form and used in the
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |