Strings, GDI+, and Error Handling in VB .NET
As you have seen in the previous chapters leading up to this point, there are many changes that have taken place in this version of VB. There are completely new approaches to development, and although some of the old functions are still in place, it is recommended that you focus on learning the new items in VB .NET rather than on functions that may or may not exist down the road.
In this chapter, we continue to look at some of these new items, and specifically deal with the changes to strings, graphics, and error handling in VB .NET.
NET Strings
If you have been using previous versions of VB, you will have undoubtedly utilized the many powerful string functions it has always offered. Like others areas of VB .NET, the string functions are still there, but they are implemented in a different manner. Now, if you remember that everything in VB .NET is considered an object (although this has been repeated many times, it is important to remember this), you will realize that as you Dim a string variable, you are actually creating an instance of the String class.
If you refer back to Chapter 5, Introduction to the VB .NET Language, in which we looked at some of the basics of the .NET language, you will see that we did a little work with strings and how they are used. We expand on that information in this chapter, beginning with the list of the common methods (see Table 7.1) that are built-in to the String class.
Class Method |
Description |
---|---|
Compare |
Compares two strings |
Concat |
Concatenates strings |
Copy |
Creates a new instance with the same value |
Equals |
Determines if two strings are equal |
Format |
Formats a string |
Equality Operator |
Allows strings to be compared |
Chars |
Returns the character at a specified position in string |
Length |
Returns the number of characters in string |
EndsWith |
Checks string to see if it ends with a specified string |
IndexOf |
Returns the index of the first character of the first occurrence of a substring within this string |
IndexOfAny |
Returns the index of the first occurrence of any character in a specified array of characters |
Insert |
Inserts a string in this string |
LastIndexOf |
Returns the index of the first character of the last occurrence of a substring within this string |
LastIndexOfAny |
Returns the index of the last occurrence of any character in a specified array of characters |
PadLeft |
Pads the string on the left |
PadRight |
Pads the string on the right |
Remove |
Deletes characters at a specified point |
Replace |
Replaces a substring with another substring |
Split |
Splits a string up into a string array |
StartsWith |
Checks if a string starts with the specified string |
SubString |
Returns a substring within the string |
ToLower |
Converts string to all lowercase letters |
ToUpper |
Converts string to all uppercase letters |
Trim |
Removes all specified characters from string |
TrimEnd |
Removes all specified characters from end of string |
TrimStart |
Removes all specified characters from beginning of string |
A quick glance at Table 7.1 is all that it takes to see some of the ways you can use the various methods that are available in .NET. Before we look at a specific example, you should be aware that the index of the first character in a VB .NET string is a zero rather than a one. In previous versions of VB, strings were one-based instead of zero-based. Although simple, it's something that you have to keep in mind as you are upgrading projects or using VB .NET to build new ones, because the old habits occasionally creep into the picture.
Here is a simple example using the string methods:
Dim strTest as String = "ABCDEFG" Dim strlength as Integer strlength = strTest.Length()
This example simply takes the string variable strTest and assigns the length of it to strlength.
We can test other features simply as well:
strTest = strTest + "HIJKLMNOP"
Now, the string that is stored in strTest is actually 'ABCDEFGHIKLMNOP'.
We use strings in many of the sample applications we develop later, so we're going to focus our attention on the new and exciting graphics capabilities offered in VB .NET.
Graphics with GDI+
In VB .NET, we have a completely new way of drawing graphics. It is based on drawing to a Graphical Device Interface (GDI) surface rather than using the old line, circle, and print methods. If you have used C++ in the past, you know the frustration that was involved in GDI development with MFC. And if you are a VB developer, you know how limited you have been with the simple methods that were available in VB6 and earlier.
In VB .NET, we now have access to GDI+. It's a superior implementation and is easier to use than traditional GDI. GDI+ provides a variety of functions. For example, if you want to set the background or foreground color of a control, you can set the ForeGroundColor property of the control.
GDI+ is easier to use, but there are also many new features that have been added, including:
- Antialiasing support
- Gradient brushes
- Splines
- Transformation and matrices
- Alpha blending
There are several namespaces that you need to become comfortable with to master GDI+ development. The GDI+ classes are grouped under six namespaces, which reside in the System.Drawing.dll assembly. These namespaces include System.Drawing, System.Drawing.Design, System.Drawing.Printing, System.Drawing.Imaging, System.Drawing.Drawing2D, and System.Drawing.Text.
Let's take a quick look at a few of these namespaces.
System Drawing Namespace
The System.Drawing namespace provides the basic GDI+ functionality. It contains the definition of basic classes, such as Brush, Pen, Graphics, Bitmap, Font, and so on. The Graphics class plays a major role in GDI+ and contains methods for drawing to the display device. Table 7.2 details some of the System.Drawing namespace classes and their definitions. Table 7.3 describes the namespace structures and their definitions.
Class |
Description |
---|---|
Bitmap |
Bitmap class |
Image |
Image class |
Brush (Brushes) |
Defines objects to fill GDI objects, such as rectangles, ellipses, polygons, and paths |
Font (FontFamily) |
Defines particular format for text, including font face, size, and style attributes |
Graphics |
Encapsulates a GDI+ drawing surface |
Pen |
Defines an object to draw lines and curves |
SolidBrush (Texture Brush) |
Fills graphics shapes using brushes |
Structure |
Description |
---|---|
Color |
RGB color |
Point (PointF) |
Represents 2D x and y coordinates. Point takes x, y values as a number. If you need to use floating-point numbers, you can use PointF. |
Rectangle (RectangleF) |
Represents a rectangle with integer values for top, left, bottom, and right. RectangleF allows you to use floating-point values. |
Size |
Defines size of a rectangular region given in width and height. SizeF takes floating numbers. |
System Drawing Drawing2D Namespace
This namespace contains 2D and vector graphics functionality. It contains classes for gradient brushes, matrix and transformation, and graphics paths. Some of the common classes are shown in Table 7.4. Table 7.5 displays the common enumerations.
Class |
Description |
---|---|
Blend (ColorBlend) |
Defines the blend for gradient brushes |
GraphicsPath |
Represents a set of connected lines and curves |
HatchBrush |
Provides a brush with hatch style, a foreground color, and a background color |
LinearGradientBrush |
Provides functionality for linear gradient |
Matrix |
Represents geometric transformation in a 3x3 matrix |
Enumeration |
Description |
---|---|
DashStyle |
Represents the style of dashed lines drawn with the Pen |
HatchStyle |
Represents different patterns available for the HatchBrush |
QualityMode |
Specifies the quality of GDI+ objects |
SmoothingMode |
Quality (smoothing) of GDI+ objects |
Graphics Class
The Graphics class is a key component of GDI+ development. Before you draw an object, such as a rectangle or line, you need a surface to draw it to. You must use the Graphics class to create these surfaces before you can draw.
There are a few ways in which you can get a graphics object to use in your application. First, you can get a graphics object in the form paint event. Another option is to override the OnPaint() method of a form. Either way, you use System.Windows.Forms.PaintEventsArgs.
Here is a simple example of overriding the OnPaint() method:
protected overrides sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) Dim g As Graphics = e.Graphics End Sub
This creates the graphics object for us and we can now use any of the methods that are included with the Graphics class. For example, we can use any of the following:
DrawArc: Draws an arc
DrawBezier (DrawBeziers): Draws Bezier curves
DrawCurve: Draws a curve
DrawEllipse: Draws an ellipse or circle
DrawImage: Draws an image
DrawLine: Draws a line
DrawPath: Draws a path
DrawPie: Draws outline of a pie section
DrawPolygon: Draws outline of a polygon
DrawRectangle: Draws outline of a rectangle
DrawString: Draws a string
FillEllipse: Fills the interior of an ellipse
FillPath: Fills the interior of a path
FillPie: Fills the interior of a pie section
FillPolygon: Fills the interior of a polygon defined by an array of points
FillRectangle: Fills the interior of a rectangle
FillRectangles: Fills the interiors of a series of rectangles
FillRegion: Fills the interior of a region
Now that we have a basic understanding of some of the things we can do, let's try a simple example to draw a line:
protected overrides sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) Dim g As Graphics = e.Graphics Dim pn As Pen = New Pen(Color.Green, 5) g.DrawLine(pn, 1, 50, 100, 500) End Sub
Objects
You have access to several types of objects when drawing items such as an ellipse and a line. There are four common GDI+ objects, detailed in the following list, which you can use to fill GDI+ items.
Brush: Used to fill enclosed surfaces with patterns, colors, or bitmaps
Pen: Used to draw lines and polygons, including rectangles, arcs, and so on
Color: Used to render a particular object (in GDI+, color can be alpha blended)
Font: Used to render text
We're going to look at a few examples of each of these.
The Brush Class
The Brush class is an abstract base class and as such, we always use its derived classes such as SolidBrush, TextureBrush, RectangleBrush, and LinearGradientBrush to instantiate a brush object.
Here is an example:
Dim brsh as SolidBrush = new SolidBrush(Color.Red), 40, 40, 140, 140
The Pen Class
A Pen, as you have already seen, draws a line of specified width and style. You can initialize a new instance of the Pen class with the specified color, a specified brush, a specified brush and width, or a specified color and width. Here is an example:
Dim pn as Pen = new Pen( Color.Blue )
The previous code initialized the Pen with the color blue. The following example initializes it and also assigns a width of 10:
Dim pn as Pen = new Pen( Color.Blue, 10 )
Color Structure
A Color structure represents an ARGB color. ARGB properties are described in the following list.
A: Alpha component value for the color
R: Red component value for the color
G: Green component value for the color
B: Blue component value for the color
You use the Color structure to change the color of an object and you can call any of its members. For example, you can change the color of a Pen as follows:
Dim pn as Pen = new Pen( Color.Red )
or
Dim pn as Pen = new Pen(Color.Green)
The Font Class
The Font class defines a particular format for text, such as font type, size, and style attributes. You can create a new instance of the Font class as follows:
Public Sub New(Font, FontStyle)
Here is an example:
Dim myFnt as Font = new Font ("Times New Roman",12)
There are many variations and possibilities of what you can do with the Font class, and we look at them more closely as we use them in the examples in this book.
Error Handling
In earlier versions of VB, we used the On Error GoTo statement to handle errors. This traditional error checking in VB has involved checking the result of a function and then acting appropriately to whatever value is returned. Although checking errors in this manner has worked, its effectiveness is often a gamble. For example, you could check the value of an incorrect value or even forget one of the values that causes an error. This leaves this type of error checking open to many more problems. There are times when you will be forced to do this, but for many errors in VB .NET, we can use exception error handling.
To perform this type of error handling at execution, we check for runtime errors that are called exceptions. When an error is encountered, the program takes the appropriate steps to continue executing. The code that is executed will only be executed when an error has occurred. We use the Try and Catch keywords in this form of error handling, which typically works as follows:
Try Code Catch Error End Try
A simple way to dissect this approach is to look at the keywords. For starters, you can consider that the Try keyword is used to begin the exception handler. You place code inside this section that you believe could cause some problems. The next section, Catch, is the executed code that tries to help your program overcome the errors. You can use multiple Catch blocks of code if you need different code for different errors. For example, suppose you have some code that is written to save a file of some type. The error handling can be present for several types of errors:
- The user didn't enter a filename.
- An invalid character was entered for the filename, such as '*'.
- A network drive that was previously existent is no longer available.
- And so forth...
You can create multiple Catch blocks that handle these errors appropriately-as you probably don't want your application responding to an invalid filename in the same way it responds to an unavailable network drive.
Here is an actual example that causes a 'Division by Zero' error:
Dim a as Integer = 10 Dim b as Integer = 0 Dim c as Integer = 0 Try b = a / c Catch MessageBox.Show(err.ToString) b=0 End Try
In the previous code, we begin with three integer variables: a, b, and c. The variable b is going to hold the value of a divided by c. Because we initialize c with a value of 0, the attempted division is met with an error. The line is inside the Try block of code, so it then moves on to the Catch block for handling the error. We display a message box that details the error and then sets the variable b equal to 0 so that the program can continue execution.
At this time, the code sets b equal to 0 regardless of the program error. We can further enhance this example by checking for the specific Divide by Zero error as follows:
Dim a as Integer = 10 Dim b as Integer = 0 Dim c as Integer = 0 Try b = a / c Catch As DivideByZeroException MessageBox.Show("You tried to divide by zero.") b=0 Catch err As Exception MessageBoxShow(err.ToString) End Try
This example checks the DivideByZeroException and if the code encounters it, it executes the appropriate code. Otherwise, it continues on and the next Catch finds any other errors that are generated.
Summary
As we have done in previous chapters, we covered a great deal of information beginning with .NET strings. From strings, we ventured into graphics with GDI +, the Graphics class, objects, and touched upon some of the error handling capabilities of VB .NET. In Chapter 8, Math and Random Number Functions in VB .NET, we cover .NET math.