BUY THIS BOOK
Add to Cart

Print Book $29.95


Add to Cart

PDF $23.99

Safari Books Online

What is this?

Add to UK Cart

Print Book £17.50

What is this?

Looking to Reprint or License this content?


Visual Basic 2005: A Developer's Notebook
Visual Basic 2005: A Developer's Notebook

By Matthew MacDonald
Book Price: $29.95 USD
£17.50 GBP
PDF Price: $23.99

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Visual Studio
The new features of Visual Basic 2005 are actually provided by three separate components: the enhanced Visual Studio 2005 IDE, a new version of the VB compiler (vbc.exe), and the revamped .NET 2.0 Framework. In this chapter, you'll start by taking Visual Studio 2005 for a spin.
At first glance, Visual Studio hasn't changed too radically in its latest incarnation. However, it's worth taking a moment to orient yourself to Microsoft's newest IDE.
Visual Studio 2005 is the direct successor to Visual Studio .NET, and it provides the most complete set of tools and features. Visual Basic 2005 Express Edition allows you to build Windows applications, console applications, and DLL components (but not web applications). Visual Web Developer 2005 Express Edition allows you to build only web applications. However, all three of these programs are really variations of the same tool—Visual Studio. As a result, the menus, toolbars, and behavior of these applications are essentially the same.
To get started and create a new project, select File New Project from the Visual Studio menu. You'll see a slightly revamped New Project dialog box, as shown in Figure 1-1. Depending on the version of Visual Studio you're using, you may see a different set of available project types.
Figure 1-1: Creating a new project
To continue, select the Windows Application project type and click OK to create the new project. In the Solution Explorer, you'll see that the project contains a single form, an application configuration file, and a My Project node (which you can select to configure project and build settings). However, the list of assembly references won't appear in the Solution Explorer, unless you explicitly choose Project Show All Files. Figure 1-2 shows both versions of the Solution Explorer.
Figure 1-2: Two views of the Solution Explorer
To save your project, choose File Save [ProjectName] from the menu. One change you're likely to notice is that Visual Studio no longer asks you to specify a directory path when you create a new project. That's because Visual Studio, in a bid to act more like Visual Basic 6, doesn't save any files until you ask it to.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
How do I do that?
To get started and create a new project, select File New Project from the Visual Studio menu. You'll see a slightly revamped New Project dialog box, as shown in Figure 1-1. Depending on the version of Visual Studio you're using, you may see a different set of available project types.
Figure 1-1: Creating a new project
To continue, select the Windows Application project type and click OK to create the new project. In the Solution Explorer, you'll see that the project contains a single form, an application configuration file, and a My Project node (which you can select to configure project and build settings). However, the list of assembly references won't appear in the Solution Explorer, unless you explicitly choose Project Show All Files. Figure 1-2 shows both versions of the Solution Explorer.
Figure 1-2: Two views of the Solution Explorer
To save your project, choose File Save [ProjectName] from the menu. One change you're likely to notice is that Visual Studio no longer asks you to specify a directory path when you create a new project. That's because Visual Studio, in a bid to act more like Visual Basic 6, doesn't save any files until you ask it to.
This behavior actually depends on the Visual Studio environment settings. When you first install Visual Studio, you have the chance to choose your developer profile. If you choose Visual Basic Development Settings, you won't be asked to save your project when you first create it.
Of course, as a savvy programmer you know that files need to reside somewhere, and if you dig around you'll find a temporary directory like C:\Documents and Settings\[UserName]\Local Settings\Application Data\Temporary Projects\[ProjectName] that's used automatically to store new, unsaved projects. Once you save a project, it's moved to the location you choose.
The process of creating web applications has also changed subtly in Visual Studio 2005, and you no longer need IIS and a virtual directory to test your web site. You'll learn more about web projects in Chapter 4
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Code, Debug, and Continue Without Restarting Your Application
Visual Basic 6 developers are accustomed to making changes on the fly, tweaking statements, refining logic, and even inserting entirely new blocks of code while they work. But the introduction of a new compile-time architecture with the .NET 1.0 common language runtime (CLR) caused this feature to disappear from Visual Studio .NET 2002 and 2003. Fortunately, it's returned in Visual Basic 2005, with a few enhancements and one major caveat—it won't work with ASP.NET.
The single most requested feature from VB 6 returns to . NET: a debugger that lets you edit code without restarting your application.
To see edit-and-debugging at its simplest, it's worth looking at an example where a problem sidelines your code—and how you can quickly recover. Figure 1-3 shows a financial calculator application that can calculate how long it will take you to become a millionaire, using Visual Basic's handy Pmt( ) function.
Figure 1-3: A simple form for a financial calculation
To create this program, first add four text boxes (the labels are optional), and then name them txtInterestRate, txtYears, txtFutureValue, and txtMonthlyPayment (from top to bottom). Then, add a button with the following event handler:
Private Sub btnCalculate_Click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles btnCalculate.Click
    
    Dim InterestRate, Years, FinalValue, MonthlyPayment As Double
    InterestRate = Val(txtInterestRate.Text)
    FinalValue = Val(txtFutureValue.Text)
    MonthlyPayment = Pmt(InterestRate / 12 / 100, _
        Years * 12, 0, -FinalValue, DueDate.BegOfPeriod)
    txtMonthlyInvestment.Text = MonthlyPayment.ToString("C")
    
End Sub
Now run the application, enter some sample values, and click the button. You'll receive a runtime exception (with the cryptically worded explanation "Argument NPer is not a valid value") when your code tries to calculate the MonthlyPayment value. One way to discover the source of the problem is to move the mouse over all the parameters in the statement and verify that they reflect what you expect. In this case, the problem is that the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Look Inside an Object While Debugging
Visual Studio has always made it possible for you to peer into variables while debugging your code, just by hovering over them with the mouse pointer. But there were always limitations. If the variable was an instance of an object, all you could see was the value returned by the ToString( ) method, which more often than not was simply the fully qualified name of the class itself. Moreover, you couldn't see the content of public properties and indexers. The Watch and Locals windows provided some improvement, but they weren't quite as convenient or intuitive. Visual Studio 2005 changes the picture with a new feature called debugger DataTips.
In Visual Studio 2005, it's even easier to take a look at the content of complex objects while debugging.
To use debugger DataTips, it helps to have a custom class to work with. The code in Example 1-1 shows the declaration for two very simple classes that represent employees and departments, respectively.
Example 1-1. Two simple classes
Public Class Employee
    Private _ID As String
    Public ReadOnly Property ID( ) As String
        Get
            Return _ID
        End Get
    End Property
    
    Private _Name As String
    Public ReadOnly Property Name( ) As String
        Get
            Return _Name
        End Get
    End Property
    
    Public Sub New(ByVal id As String, ByVal name As String)
        _ID = id
        _Name = name
    End Sub
End Class
    
Public Class Department
    Private _Manager As Employee
    Public ReadOnly Property Manager( ) As Employee
        Get
            Return _Manager
        End Get
    End Property
    
    Private _DepartmentName As String
    Public ReadOnly Property Name( ) As String
        Get
            Return _DepartmentName
        End Get
    End Property
    
    Public Sub New(ByVal departmentName As String, ByVal manager As Employee)
        _DepartmentName = departmentName
        _Manager = manager
    End Sub
End Class
Now you can add some code that uses these objects. Add the following event handler to any form to create a new
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Diagnose and Correct Errorson the Fly
Visual Studio does a great job of catching exceptions, but it's not always as helpful at resolving them. The new Exception Assistant that's hardwired into Visual Studio 2005 gives you a head start.
Stumbled into a head-scratching exception? Visual Studio 2005 gives you a head start for resolving common issues with its Exception Assistant.
You don't need to take any steps to activate the Exception Assistant. Instead, it springs into action as soon as your program encounters an unhandled exception.
To see it in action, you need to create some faulty code. A good test is to add the following event handler to any form, which tries to open a non-existent file:
Private Sub Form1_Load(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles MyBase.Load
    
    Dim XMLText As String = My.Computer.FileSystem.ReadAllText( _
      "c:\FileDoesNotExist")
    
End Sub
Now run the application. When the error occurs, Visual Studio switches into break mode and highlights the offending statement. The Exception Assistant then appears, with a list of possible causes for the problem. Each suggestion appears as a separate link in the pop-up window. If you click one of these links, the full MSDN help topic will appear. Figure 1-7 shows the result with the faulty file-reading code; the Exception Assistant correctly identifies the reason that the attempt to open the file failed.
Figure 1-7: Getting help with an exception
This example uses a new VB language feature—the My object. You'll learn much more about My objects in the next chapter.
If you want to see the low-level exception information, click the View Detail link at the bottom of the window. This pops up a dialog box with a PropertyGrid showing all the information of the associated exception object. This change alone is a great step forward from Visual Studio .NET 2003, where you needed to write a Catch exception handler and set a breakpoint to take a look at the underlying exception object.
...solving complex problems? The Exception Assistant isn't designed to help you sort through issues of any complexity. Instead, it works best at identifying the all-too-common "gotchas," such as trying to use a null reference (usually a result of forgetting to use the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Rename All Instances of Any Program Element
Symbolic rename allows you to rename all instances of any element you declare in your program, from classes and interfaces to properties and methods, in a single step. This technique, which is decidedly not a simple text search-and-replace feature by virtue of its awareness of program syntax, solves many knotty problems found in previous releases of Visual Basic. For example, imagine you want to rename a public property named FirstName. If you use search-and-replace, you'll also inadvertently affect a text box named txtFirstName, an event handler named cmdFirstName_Click, a database field accessed through row("FirstName"), and even your code comments. With symbolic rename, the IDE takes care of renaming just what you want, and it completes all of its work in a single step.
Need to rename a method, property, or variable without mangling other similar names in the same file? Visual Studio 2005 includes the perfect antidote to clumsy search-and-replace.
You can use symbolic rename from any code window. To understand how it works, create a form that has a single text box named TextBox1 and a button named cmdText. Finally, add the form code in Example 1-2.
Example 1-2. A simple form that uses the word "Text" heavily
Public Class TextTest
    
    Private Sub TextTest_Load(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load
        ' Get the text from the text box.
        Dim Text As String = TextBox1.Text
    
        ' Convert and display the text.
        Text = ConvertText(Text)
        MessageBox.Show("Uppercase Text is: " & Text)
    End Sub
    
    Public Function ConvertText(ByVal Text As String) As String
        Return Text.ToUpper( )
    End Function
    
End Class
This code performs a relatively mundane task: converting a user-supplied string to uppercase and displays it in a message box. What's notable is how many places it uses the word "Text." Now, consider what happens if you need to rename the local variable
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Use IntelliSense Filteringand AutoCorrect
IntelliSense is one of the great conveniences of Visual Studio, and it continues to improve in Visual Studio 2005, with two new features that make it more useful: IntelliSense filtering and AutoCorrect. IntelliSense filtering restricts the number of options you see to those that make sense in the current context. AutoCorrect goes one step further by recommending ways to resolve syntax errors, rather than simply reporting them.
Visual Studio 2005 makes IntelliSense more intelligent by restricting class names that aren't relevant and suggesting corrections you can apply to resolve syntax errors.
There's no need for any extra steps when you use IntelliSense filtering—it's at work automatically. As you enter code, IntelliSense prompts you with lists of classes, properties, events, and more. In Visual Studio 2005, this list is tailored to your immediate needs, based on various contextual details. For example, if you're selecting an attribute to apply to a method, the IntelliSense list will show only classes that derive from the base Attribute class.
To see the new IntelliSense in action, start typing an exception-handling block. When you enter the Catch block, the IntelliSense list will show only classes that derive from the base Exception class (as shown in Figure 1-8). Select the Common or All tab at the bottom of the list, depending on whether you want to see the most commonly used classes or every possibility.
Figure 1-8: Filtering for Exception classes only
AutoCorrect is an IntelliSense improvement that targets syntax errors. Every time Visual Studio discovers a problem, it underlines the offending code in blue. You can hover over the problem to see a ToolTip with error information. With AutoCorrect, Visual Studio also adds a red error icon that, when clicked, shows a window with the suggested correction.
To see AutoCorrect in action, enter the following code (which attempts to assign a string to an integer without proper type-casting code):
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Edit Control Properties in Place
The Properties window in Visual Studio makes control editing easy, but not always fast. For example, imagine you want to tweak all the text on a form. In previous versions of Visual Studio, the only option was to select each control in turn and modify the Text property in the Properties window one at a time. Although this approach isn't necessarily awkward, it certainly isn't as easy as it could be. In Visual Studio 2005, you can adjust a single property for a series of controls directly on the form.
When you need to update a single property for a number of different controls, in-place property editing makes it easy.
To try in-place property editing, create a new form and add an assortment of controls. (The actual controls you use don't really matter, but you should probably include some text boxes, buttons, and labels.) Then, select View Property Editing View. Finally, choose the property you want to change from the drop-down list above the form design surface. By default, the Name property is selected, but Figure 1-10 shows an example with the Text property.
Figure 1-10: Editing a single property for multiple controls
In property-editing view, an edit box appears over every control on the form with the contents of the selected property. You can edit the value of that property by simply clicking on the edit box and entering the new value. You can also jump from one control to the next by pressing the Tab key.
When you are finished with your work, again select View Property Editing View, or click the Exit Mode link next to the property drop-down list.
...editing tab order? Visual Studio allows you to easily edit tab order by clicking controls in the order that you want users to be able to navigate through them. Select a form with at least one control, and choose View Tab Order to activate this mode, which works the same as it did in Visual Studio 2003.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Call Methods at Design Time
Although Visual Studio .NET 2003 included the Immediate window, you couldn't use it to execute code at design time. Longtime VB coders missed this feature, which was a casualty of the lack of a background compiler. In Visual Studio 2005, this feature returns along with the return of a background compiler.
Need to try out a freshly written code routine? Visual Studio 2005 lets you run it without starting your project.
You can use the Immediate window to evaluate simple expressions, and even to run subroutines in your code. To try out this technique, add the following shared method to a class:
Public Shared Function AddNumbers(ByVal A As Integer, _
  ByVal B As Integer) As Integer
    
    Return A + B
    
End Sub
By making this a shared method, you ensure that it's available even without creating an instance of the class. Now, you can call it easily in the design environment.
By default, the Immediate window isn't shown at design time. To show it, select Debug Windows Command from the menu. Statements inside the Immediate window usually start with ? (a shorthand for Print, which instructs Visual Studio to display the result). You can enter the rest of the statement like any other line of code, with the benefit of IntelliSense. Figure 1-11 shows an example in which the Command window is used to run the shared method just shown.
Figure 1-11: Executing code at design time
When you execute a statement like the one shown in Figure 1-11, there will be a short pause while the background compiler works (and you'll see the message "Build started" in the status bar). Then the result will appear.
The expression evaluation in the beta release of Visual Studio 2005 is a little quirky. Some evaluations won't work, and will simply launch your application without returning a result. Look for this to improve in future builds.
The MSDN help includes more information about supported expression types at the index entry "expressions about expressions."
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Insert Boilerplate CodeUsing Snippets
Some code is common and generic enough that programmers everywhere write it again and again each day. Even though developers have the help of online documentation, samples, and books like the one you're reading, useful code never seems to be at your fingertips when you need it. Visual Studio 2005 includes a new code snippet feature that allows you to insert commonly used code and quickly adapt it to suit your purposes. Early beta builds of Visual Studio 2005 included a tool for building your own snippets. Although this feature isn't in the latest releases, Microsoft has suggested that it might appear as a separate add-on tool at a later time.
Looking for the solution to an all-too-common nuisance? Visual Studio code snippets might already have the answer.
You can insert a code snippet anywhere in your code. Just move to the appropriate location, right-click the mouse on the current line, and select Insert Snippet. A pop-up menu will appear with a list of snippet categories, such as Math, Connectivity and Networking, and Working with XML. Once you select a category, a menu will appear with a list of snippets. Once you select a snippet, the code will be inserted.
For example, suppose you want to add the ability to send and receive email messages to your application. Just create a new event handler or a standalone method, and right-click inside it. Then, choose Insert Snippet, and select Connectivity and Networking Create an Email Message. Figure 1-12 shows the code that's inserted.
Figure 1-12: Customizing a code snippet
The shaded portions of code are literal values (like file paths and control references) that you need to customize to adapt the code to your needs. By pressing the Tab key, you can move from one shaded region to the next. Additionally, if you hover over a shaded region, a ToolTip will appear with a description of what content you need to insert.
...getting more snippets? The basic set of code snippets included with Visual Studio .NET is fairly modest. It includes some truly useful snippets (e.g., "Find a Node in XML Data") and some absurdly trivial ones (e.g., "Add a Comment to Your Code"). However, many useful topics, such as encryption, aren't dealt with at all.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Create XML Documentation for Your Code
Properly commenting and documenting code takes time. Unfortunately, there's no easy way to leverage the descriptive comments you place in your code when it comes time to produce more detailed API references and documentation. Instead, you typically must create these documents from scratch.
Use XML comments to effortlessly create detailed code references,a feature C# programmers have had since . NET 1.0.
Visual Studio 2005 changes all this by introducing a feature that's been taken for granted by C# programmers since .NET 1.0—XML comments. With XML comments, you comment your code using a predefined format. Then, you can use other tools to extract these comments and use them to build other documents. These documents can range from help documentation to specialized code reports (for example, a list of unresolved issues, legacy code, or code review dates).
XML comments are distinguished from ordinary comments by their format. First of all, XML comments start with three apostrophes (rather than just one). Here's an example:
''' <summary>This is the summary.</summary>
As you can see, XML comments also have another characteristic—they use tag names. The tag identifies the type of comment. These tags allow you to distinguish between summary information, information about a specific method, references to other documentation sections, and so on.
The most commonly used XML comment tags include:
<summary>
Describes a class or another type. This is the highest-level information for your code.
<remarks>
Allows you to supplement the summary information. This tag is most commonly used to give a high-level description of each type member (e.g., individual methods and properties).
<param>
Describes the parameters accepted by a method. Add one <param> tag for each parameter.
<returns>
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: The Visual Basic Language
When Visual Basic .NET first appeared, loyal VB developers were shocked to find dramatic changes in their favorite language. Suddenly, common tasks such as instantiating an object and declaring a structure required new syntax, and even basic data types like the array had been transformed into something new. Fortunately, Visual Basic 2005 doesn't have the same shocks in store. The language changes in the latest version of VB are refinements that simplify life without making any existing code obsolete. Many of these changes are language features imported from C# (e.g., operator overloading), while others are completely new ingredients that have been built into the latest version of the common language runtime (e.g., generics). In this chapter, you'll learn about all the most useful changes to the VB language.
The new My objects provide easy access to various features that developers often need but don't necessarily know where to find in the sprawling .NET class library. Essentially, the My objects offer one-stop shopping, with access to everything from the Windows registry to the current network connection. Best of all, the My object hierarchy is organized according to use and is easy to navigate using Visual Studio IntelliSense.
There are seven first-level My objects. Out of these, three core objects centralize functionality from the .NET Framework and provide computer information. These include:
Tired of hunting through the extensive . NET class library in search of what you need? With the new My objects, you can quickly find some of the most useful features . NET has to offer.
My.Computer
This object provides information about the current computer, including its network connection, the mouse and keyboard state, the printer and screen, and the clock. You can also use this object as a jumping-off point to play a sound, find a file, access the registry, or use the Windows clipboard.
My.Application
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Use the My Objects to Program Common Tasks
The new My objects provide easy access to various features that developers often need but don't necessarily know where to find in the sprawling .NET class library. Essentially, the My objects offer one-stop shopping, with access to everything from the Windows registry to the current network connection. Best of all, the My object hierarchy is organized according to use and is easy to navigate using Visual Studio IntelliSense.
There are seven first-level My objects. Out of these, three core objects centralize functionality from the .NET Framework and provide computer information. These include:
Tired of hunting through the extensive . NET class library in search of what you need? With the new My objects, you can quickly find some of the most useful features . NET has to offer.
My.Computer
This object provides information about the current computer, including its network connection, the mouse and keyboard state, the printer and screen, and the clock. You can also use this object as a jumping-off point to play a sound, find a file, access the registry, or use the Windows clipboard.
My.Application
This object provides information about the current application and its context, including the assembly and its version, the folder where the application is running, the culture, and the command-line arguments that were used to start the application. You can also use this object to log an application event.
My.User
This object provides information about the current user. You can use this object to check the user's Windows account and test what groups the user is a member of.
Along with these three objects, there are another two objects that provide default instances. Default instances are objects that .NET creates automatically for certain types of classes defined in your application. They include:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Get Application Information
The My.Application object provides a wealth of information right at your fingertips. Getting this information is as easy as retrieving a property.
Using the My.Application object, you can get information about the current version of your application, where it's located, and what parameters were used to start it.
The information in the My.Application object comes in handy in a variety of situations. Here are two examples:
  • You want to get the exact version number. This could be useful if you want to build a dynamic About box, or check with a web service to make sure you have the latest version of an assembly.
  • You want to record some diagnostic details. This becomes important if a problem is occurring at a client site and you need to log some general information about the application that's running.
To create a straightforward example, you can use the code in Example 2-1 in a console application. It retrieves all of these details and displays a complete report in a console window.
Example 2-1. Retrieving information from My.Application
' Find out what parameters were used to start the application.
Console.Write("Command line parameters: ")
For Each Arg As String In My.Application.CommandLineArgs
    Console.Write(Arg & " ")
Next
Console.WriteLine( )
Console.WriteLine( )
    
' Find out some information about the assembly where this code is located.
' This information comes from metadata (attributes in your code).
Console.WriteLine("Company: " & My.Application.Info.CompanyName)
Console.WriteLine("Description: " & My.Application.Info.Description)
Console.WriteLine("Located in: " & My.Application.Info.DirectoryPath)
Console.WriteLine("Copyright: " & My.Application.Info.Copyright)
Console.WriteLine("Trademark: " & My.Application.Info.Trademark)
Console.WriteLine("Name: " & My.Application.Info.AssemblyName)
Console.WriteLine("Product: " & My.Application.Info.ProductName)
Console.WriteLine("Title: " & My.Application.Info.Title)
Console.WriteLine("Version: " & My.Application.Info.Version.ToString( ))
Console.WriteLine( )
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Use Strongly Typed Resources
In addition to code, .NET assemblies can also contain resources—embedded binary data such as images and hardcoded strings. Even though .NET has supported a system of resources since Version 1.0, Visual Studio hasn't included integrated design-time support. As a result, developers who need to store image data usually add it to a control that supports it at design time, such as a PictureBox or ImageList. These controls insert the picture data into the application resource file automatically.
Strongly typed resources let you embed static data such as images into your compiled assemblies, and access it easily in your code.
In Visual Studio 2005, it's dramatically easier to add information to the resources file and update it afterward. Even better, you can access this information in a strongly typed fashion from anywhere in your code.
In order to try using a strongly typed resource of an image in this lab, you need to create a new Windows application before continuing.
To add a resource, start by double-clicking the My Project node in the Solution Explorer. This opens up the application designer, where you can configure a host of application-related settings. Next, click the Resources tab. In the Categories drop-down listbox, select the type of resources you want to see (strings, images, audio, and so on). The string view shows a grid of settings. The image view is a little different—by default, it shows a thumbnail of each picture.
To add a new picture, select the Images category from the drop-down list and then select Add Existing File from the toolbar. Browse to an image file, select it, and click OK. If you don't have an image file handy, try using one from the Windows directory, such as winnt256.bmp (which is included with most versions of Windows).
By default, the resource name has the same name as the file, but you can rename it after adding it. In this example, rename the image to EmbeddedGraphic (as shown in Figure 2-2).
Figure 2-2: Adding a picture as a strongly typed resource
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Use Strongly Typed Configuration Settings
Applications commonly need configuration settings to nail down details like file locations, database connection strings, and user preferences. Rather than hardcoding these settings (or inventing your own mechanism to store them), .NET lets you add them to an application-specific configuration file. This allows you to adjust values on a whim by editing a text file without recompiling your application.
Use error-proof configuration settings by the application designer.
In Visual Studio 2005, configuration settings are even easier to use. That's because they're automatically compiled into a custom class that provides strongly typed access to them. That means you can retrieve settings using properties, with the help of IntelliSense, instead of relying on string-based lookups. Even better, .NET enhances this model with the ability to use updatable, user-specific settings to track preferences and other information. You'll see both of these techniques at work in this lab.
Every custom configuration setting is defined with a unique string name. In previous versions of .NET, you could retrieve the value of a configuration setting by looking up the value by its string name in a collection. However, if you use the wrong name, you wouldn't realize your error until you run the code and it fails with a runtime exception.
In Visual Studio 2005, the story is much improved. To add a new configuration setting, double-click the My Project node in the Solution Explorer. This opens up the application designer where you can configure a host of application-related settings. Next, click the Settings tab, which shows a list of custom configuration settings where you can define new settings and their values.
To add a custom configuration setting to your application, enter a new setting name at the bottom of the list. Then specify the data type, scope, and the actual content of the setting. For example, to add a setting with a file path, you might use the name UserDataFilePath, the type String, the scope Application (you'll learn more about this shortly), and the value
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Build Typesafe Generic Classes
Programmers often face a difficult choice. On one hand, it's keenly important to build solutions that are as generic as possible, so that they can be reused in different scenarios. For example, why build a CustomerCollection class that accepts only objects of type Customer when you can build a generic Collection class that can be configured to accept objects of any type? On the other hand, performance and type safety considerations can make a generic solution less desirable. If you use a generic .NET Collection class to store Customer objects, for example, how can you be sure that someone won't accidentally insert another type of object into the collection, causing an insidious problem later on?
Need to create a class that's flexible enough to work with any type of object, but able to restrict the objects it accepts in any given instance? With generics, VB has the perfect solution.
Visual Basic 2005 and .NET 2.0 provide a solution called generics. Generics are classes that are parameterized by type. In other words, generics allow you to create a class template that supports any type. When you instantiate that class, you specify the type you want to use, and from that point on, your object is "locked in" to the type you chose.
An example of where the use of generics makes great sense is the System.Collections.ArrayList class. ArrayList is an all-purpose, dynamically self-sizing collection. It can hold ordinary .NET objects or your own custom objects. In order to support this, ArrayList treats everything as the base Object type.
The problem is that there's no way to impose any restrictions on how ArrayList works. For example, if you want to use ArrayList to store a collection of Customer objects, you have no way to be sure that a faulty piece of code won't accidentally insert strings, integers, or some other type of object, causing future headaches. For this reason, developers often create their own strongly typed collection classes—in fact, the .NET class library is filled with dozens of them.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Make Simple Data Types Nullable
With the new support for generics that's found in the .NET Framework, a number of new features become possible. One of these features—generic strongly typed collections—was demonstrated in the previous lab, "Build Typesafe Generic Classes." Now you'll see another way that generics can solve common problems, this time by using the new nullable data types.
Do you need to represent data that may or may not be present? VB . NET's new nullable types fill the gap.
A null value (identified in Visual Basic by the keyword Nothing), is a special flag that indicates no data is present. Most developers are familiar with null object references, which indicate that the object has been defined but not created. For example, in the following code, the FileStream contains a null reference because it hasn't been instantiated with the New keyword:
Dim fs As FileStream
If fs Is Nothing
    ' This is always true because the FileStream hasn't
    ' been created yet.
    Console.WriteLine("Object contains a null reference.")
End If
Core data types like integers and strings can't contain null values. Numeric variables are automatically initialized to 0. Boolean variables are False. String variables are set to an empty string (''") automatically. In fact, even if you explicitly set a simple data type variable to Nothing in your code, it will automatically revert to the empty value (0, False, or ""), as the following code demonstrates:
Dim j As Integer = Nothing
If j = 0 Then
    ' This is always true because there is an
    ' implicit conversion between Nothing and 0 for integers.
    Console.WriteLine("Non-nullable integer j = " & j)
End If
This design sometimes causes problems, because there's no way to distinguish between an empty value and a value that was never supplied in the first place. For example, imagine you create code that needs to retrieve the number of times the user has placed an order from a text file. Later on, you examine this value. The problem occurs if this value is 0. Quite simply, you have no way to know whether this is valid data (the user placed no orders), or it represents missing information (the setting couldn't be retrieved or the current user isn't a registered customer).
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Use Operators with Custom Objects
Every VB programmer is familiar with the arithmetic operators for addition (+), subtraction (-), division (/), and multiplication (*). Ordinarily, these operators are reserved for .NET numeric types, and have no meaning when used with other objects. However, in VB .NET 2.0 you can build objects that support all of these operators, as well as the operators used for logical operations and implicit conversion). This technique won't make sense for business objects, but it is extremely handy if you need to model mathematical structures such as vectors, matrixes, complex numbers, or—as demonstrated in the following example—fractions.
Tired of using clumsy syntax like ObjA.Subtract(ObjB) to perform simple operations on your custom objects? With VB's support for operator overloading, you can manipulate your objects as easily as ordinary numbers.
To overload an operator in Visual Basic 2005, you need to create a special operator method in your class (or structure). This method must be declared with the keywords Public Shared Operator, followed by the symbol for the operator (e.g., +).
To overload an operator simply means to define what an operator does when used with a specific type of object. In other words, when you overload the + operator for a Fraction class, you tell .NET what to do when your code adds two Fraction objects together.
For example, here's an operator method that adds support for the addition (+) operator:
Public Shared Operator+(objA As MyClass, objB as MyClass) As MyClass
    ' (Code goes here.)
End Operator
Every operator method accepts two parameters, which represent the values on either side of the operator. Depending on the class and the operator, order may be important (as it is for division).
Once you've defined an operator, the VB compiler will call your code when it executes a statement that uses the operator with your class. For example, the compiler changes code like this:
ObjC = ObjA + ObjB
into this:
ObjC = MyClass.Operator+(ObjA, ObjB)
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Split a Class into Multiple Files
If you've cracked open a .NET 2.0 Windows Forms class, you'll have noticed that all the automatically generated code is missing! To understand where it's gone, you need to learn about a new feature called partial classes, which allow you to split classes into several pieces.
Have your classes grown too large to manage in one file? With the new Partial keyword, you can split a class into separate files.
Using the new Partial keyword, you can split a single class into as many pieces as you want. You simply define the same class in more than one place. Here's an example that defines a class named SampleClass in two pieces:
Partial Public Class SampleClass
    Public Sub MethodA( )
        Console.WriteLine("Method A called.")
    End Sub
End Class
    
Partial Public Class SampleClass
    Public Sub MethodB( )
        Console.WriteLine("Method B called.")
    End Sub
End Class
In this example, the two declarations are in the same file, one after the other. However, there's no reason that you can't put the two SampleClass pieces in different source code files in the same project. (The only restrictions are that you can't define the two pieces in separate assemblies or in separate namespaces.)
When you build the application containing the previous code, Visual Studio will track down each piece of SampleClass and assemble it into a complete, compiled class with two methods, MethodA( ) and MethodB( ). You can use both methods, as shown here:
Dim Obj As New SampleClass( )
Obj.MethodA( )
Obj.MethodB( )
Partial classes don't offer you much help in solving programming problems, but they can be useful in breaking up extremely large, unwieldy classes. Of course, the existence of large classes in your application could be a sign that you haven't properly factored your problem, in which case you should really break your class down into separate, not partial, classes. One of the key roles of partial classes in .NET is to hide the designer code that is automatically generated by Visual Studio, whose visibility in previous versions has been a source of annoyance to some VB programmers.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Extend the My Namespace
The My objects aren't defined in a single place. Some come from classes defined in the Microsoft.VisualBasic.MyServices namespace, while others are generated dynamically as you add forms, web services, configuration settings, and embedded resources to your project. However, as a developer you can participate in the My namespace and extend it with your own ingredients (e.g., useful calculations and tasks that are specific to your application).
Do you use the My objects so much you'd like to customize them yourself? VB 2005 lets you plug in your own classes.
To plug a new class into the My object hierarchy, simply use a Namespace block with the name My. For example, you could add this code to create a new BusinessFunctions class that contains a company-specific function for generating custom identifiers (by joining the customer name to a new GUID):
Namespace My
    
    Public Class BusinessFunctions
        Public Shared Function GenerateNewCustomerID( _
          ByVal name As String) As String
            Return name & "_" & Guid.NewGuid.ToString( )
        End Function
    End Class
    
End Namespace
Once you've created the BusinessFunctions object in the right place, you can make use of it in your application just like any other My object. For example, to display a new customer ID:
Console.WriteLine(My.BusinessFunctions.GenerateNewCustomerID("matthew"))
Note that the My classes you add need to use shared methods and properties. That's because the My object won't be instantiated automatically. As a result, if you use ordinary instance members, you'll need to create the My object on your own, and you won't be able to manipulate it with the same syntax. Another solution is to create a module in the My namespace, because all the methods and properties in a module are always shared.
You can also extend some of the existing My objects thanks to partial classes. For example, using this feature you could add new information to the My.Computer object or new routines to the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Skip to the Next Iteration of a Loop
The Visual Basic language provides a handful of common flow control statements, which let you direct the execution of your code. For example, you can use Return to step out of a function, or Exit to back out of a loop. However, before VB 2005, there wasn't any way to skip to the next iteration of a loop.
VB's new Continue keyword gives you a quick way to step out of a tangled block of code in a loop and head straight into the next iteration.
The Continue statement is one of those language details that seems like a minor frill at first, but quickly proves itself to be a major convenience. The Continue statement exists in three versions: Continue For, Continue Do, and Continue While, each of which is used with a different type of loop (For ... Next, Do ... Loop, or While ... End While).
To see how the Continue statement works consider the following code:
For i = 1 to 1000
    If i Mod 5 = 0 Then
        ' (Task A code.)
        Continue For
    End If
    ' (Task B code.)
Next
This code loops 1,000 times, incrementing a counter i. Whenever i is divisible by five, the task A code executes. Then, the Continue For statement is executed, the counter is incremented, and execution resumes at the beginning of the loop, skipping the code in task B.
In this example, the continue statement isn't really required, because you could rewrite the code easily enough as follows:
For i = 1 to 1000
    If i Mod 5 = 0 Then
        ' (Task A code.)
    Else
        ' (Task B code.)
    End If
Next
However, this isn't nearly as possible if you need to perform several different tests. To see the real benefit of the Continue statement, you need to consider a more complex (and realistic) example.
Example 2-5 demonstrates a loop that scans through an array of words. Each word is analyzed, and the program decides whether the word is made up of letters, numeric characters, or the space character. If the program matches one test (for example, the letter test), it needs to continue to the next word without performing the next test. To accomplish this without using the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Dispose of Objects Automatically
In .NET, it's keenly important to make sure objects that use unmanaged resources (e.g., file handles, database connections, and graphics contexts) release these resources as soon as possible. Toward this end, such objects should always implement the IDisposable interface, and provide a Dispose( ) method that you can call to release their resources immediately.
Worried that you'll have objects floating around in memory, tying up resources until the garbage collector tracks them down? With the Using statement, you can make sure disposable objects meet with a timely demise.
The only problem with this technique is that you must always remember to call the Dispose( ) method (or another method that calls Dispose( ), such as a Close( ) method). VB 2005 provides a new safeguard you can apply to make sure Dispose( ) is always called: the Using statement.
You use the Using statement in a block structure. In the first line, when you declare the Using block, you specify the disposable object you are using. Often, you'll also create the object at the same time using the New keyword. Then, you write the code that uses the disposable object inside the Using block. Here's an example with a snippet of code that creates a new file and writes some data to the file:
Using NewFile As New System.IO.StreamWriter("c:\MyFile.txt")
    NewFile.WriteLine("This is line 1")
    NewFile.WriteLine("This is line 2")
End Using
    
' The file is closed automatically. 
' The NewFile object is no longer available here.
In this example, as soon as the execution leaves the Using block, the Dispose( ) method is called on the NewFile object, releasing the file handle.
...errors that occur inside a Using block? Thankfully, .NET makes sure it disposes of the resource no matter how you exit the Using block, even if an unhandled exception occurs.
The Using statement makes sense with all kinds of disposable objects, such as:
  • Files (including FileStream, StreamReader, and StreamWriter)
  • Database connections (including
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Safeguard Properties with Split Accessibility