Enhancing a Sample Application

Switch your display to the Design view. Before you drag a control onto the WPF design surface you are first going to slightly customize the Grid control that is already part of your window. The goal is to define a row definition in the default grid that was generated with your baseline WPF class. As noted, the default window that was created has a Grid that fills the display area. Using your mouse, click on a spot just to the left of the Grid, but about a finger's width below the top of the Grid. This should create a thin horizontal line across your window. In your XAML below the design surface you'll see some new XML that describe your new row.

Once you have defined this row, go over to the properties for your Grid and change the background color of the Grid to black. To do this first make sure the Grid is selected in the designer. Then move to the top of the list of property categories where you should find the ‘Brush' category, and select it. To change the value of this property from No Brush, which you'll see is the current selection, select the next rectangle icon for a solid brush. The display will dynamically change within the properties window and you'll see a full color selector. For simplicity, just assign a black brush to the background.

To add more controls to your application, you are going to use the control Toolbox. The Toolbox window is available whenever a form is in Design view. By default, the Toolbox (see Figure 1.15) is docked to the left side of Visual Studio as a tab. When you click this tab, the control window expands, and you can drag controls onto your form. Alternatively, if you have closed the Toolbox tab, you can go to the View menu and select Toolbox.

Figure 1.15 Visual Studio with sample ProVB_VS2012 in the designer

1.15

If you haven't set up the Toolbox to be permanently visible, it will slide out of the way and disappear whenever focus is moved away from it. This helps maximize the available screen real estate. If you don't like this feature (and you won't while working to add controls) you can make the Toolbox permanently visible by clicking the pushpin icon on the Toolbox's title bar.

By default the Toolbox contains the standard controls. All controls loaded in the Toolbox are categorized so it's easier to find them. Before customizing the first control added to this form, take a closer look at the Visual Studio Toolbox. The tools are broken out by category, but this list of categories isn't static. Visual Studio allows you to create your own custom controls. When you create such controls, the IDE will—after the controls have been compiled—automatically add them to the display when you are working in the same solution as the controls. These would be local references to controls that become available within the current solution.

Additionally, depending on whether you are working on a Web or a Windows Forms application, your list of controls in the Toolbox will vary. Windows Forms has a set of controls that leverages the power of the Windows operating system. Web applications, conversely, tend to have controls oriented to working in a disconnected environment.

It's also possible to have third-party controls in your environment. Such controls can be registered with Visual Studio and are then displayed within every project you work on. When controls are added to the Toolbox they typically appear in their own custom categories so that they are grouped together and therefore easy to find.

Next, go to the Toolbox and drag a button onto the top row of the display that you created earlier. Now take a scroll viewer and deposit it within the bottom section of the grid. For the next step you're going to go to the XAML, which is below your Design view. The design will have assigned a group of properties, and your first task is to remove most of these. Your XAML should include a line similar to the following:

<ScrollViewer HorizontalAlignment="Left" Height="100" Margin="138,80,0,0" 
              Grid.Row="1" VerticalAlignment="Top" Width="100"/>

You want to transform that line into one that looks like the following:

<ScrollViewer  Margin="0,0,0,0" Grid.Row="1"></ScrollViewer>

Notice that you've modified the values for the Margin to be all zero. Additionally, instead of the XML being a self-terminating declaration, you've separated out the termination of the XML.

You'll see that the border of the control now fills the lower section of your display. That means the scroll view control is now ready to have a textbox placed on it. Drag and drop one from the Toolbox, and you'll see your XAML transform to include the following line—and it should have appeared before the start and end tags for the scroll viewer you just added.

<TextBox Height="23" TextWrapping="Wrap" Text="TextBox" Width="120"/>   

Once again you are going to edit this line of XML to simplify it. In this case you want to remove the size attributes and default contents and provide a name for your textbox control so you can reference it from code. The result should be something similar to the following line of XML.

<TextBox Name="TextBoxResult" TextWrapping="Wrap" />

Finally, select the button you originally dropped on the form. Go to the Properties window and select the Common category. The first property in that category should be Content, and you want to set the label to “Run Sample.” Once you've done this, resize the button to display your text. At this point your form should look similar to what is seen in Figure 1.15, introduced earlier in this chapter.

Return to the button you've dragged onto the form. It's ready to go in all respects—however, Visual Studio has no way of knowing what you want to happen when it is used. Having made these changes, double-click the button in the Display view. Double-clicking tells Visual Studio that you want to add an event handler to this control, and by default Visual Studio adds an On_Click event handler for buttons. The IDE then shifts the display to the Code view so that you can customize this handler. Notice that you never provided a name for the button. It doesn't need one—the hook to this handler is defined in the XAML, and as such there is no reason to clutter the code with an extra control name.

Customizing the Code

With the code window open to the newly added event handler for the Button control, you can start to customize this handler. Although the event handler can be added through the designer, it's also possible to add event handlers from Code view. After you double-clicked the button, Visual Studio transferred you to Code view and displayed your new event handler. Notice that in Code view there are drop-down lists on the top of the edit window. The boxes indicate the current “named” object on the left—in this case, your main window—and the current method on the right—in this case, the click event handler. You can add new handlers for other events for the selected object using these drop-down lists.

The drop-down list on the left side contains only those objects which have been named. Thus, your button isn't listed, but the first named parent for that control is selected: MainWindow. While you can create events for unnamed controls, you can only create handlers in code for named objects. The drop-down list on the right side contains all the events for the selected object only. For now, you have created a new handler for your button's click event, so now you can customize the code associated with this event. Figure 1.16 shows the code for this event handler with generated XML Comments.

Figure 1.16 Button_Click_1 event handler

1.16

Adding XML Comments

One of Visual Studio's features is the capability to generate an XML comments template for Visual Basic. XML comments are a much more powerful feature than you might realize, because they are also recognized by Visual Studio for use in IntelliSense. To add a new XML comment to your handler, go to the line before the handler and type three single quotation marks: ‘'’. This triggers Visual Studio to replace your single quotation marks with the following block of comments. You can trigger these comments in front of any method, class, or property in your code.

 ''' <summary>
 '''
 ''' </summary>
 ''' <param name="sender"></param>
 ''' <param name="e"></param>
 ''' <remarks></remarks>

Visual Studio provides a template that offers a place to include a summary of what this method does. It also provides placeholders to describe each parameter that is part of this method. Not only are the comments entered in these sections available within the source code, when it's compiled you'll also find an XML file in the project directory, which summarizes all your XML comments and can be used to generate documentation and help files for the said source code. By the way, if you refactor a method and add new parameters, the XML comments also support IntelliSense for the XML tags that represent your parameters.

IntelliSense, Code Expansion, and Code Snippets

One of the reasons why Microsoft Visual Studio is such a popular development environment is because it was designed to support developer productivity. People who are unfamiliar with Visual Studio might just assume that “productivity” refers to organizing and starting projects. Certainly, as shown by the project templates and project settings discussed so far, this is true, but those features don't speed your development after you've created the project.

This section covers three features that target your productivity while writing code. They are of differing value and are specific to Visual Studio. The first, IntelliSense, has always been a popular feature of Microsoft tools and applications. The second feature, code expansion, is another popular feature available since Visual Studio 2005. It enables you to type a keyword, such as “select,” and then press the Tab key to automatically insert a generic select-case code block which you can then customize. Finally, going beyond this, you can use the right mouse button and insert a code snippet at the location of your mouse click. As you can tell, each of these builds on the developer productivity capabilities of Visual Studio.

IntelliSense

Early versions of IntelliSense required you to first identify a class or property in order to make uses of the IntelliSense feature. Now IntelliSense is activated with the first letter you type, so you can quickly identify classes, commands, and keywords that you need.

Once you've selected a class or keyword, IntelliSense continues, enabling you to not only work with the methods of a class, but also automatically display the list of possible values associated with an enumerated list of properties when one has been defined. IntelliSense also provides a tooltip-like list of parameter definitions when you are making a method call.

Figure 1.17 illustrates how IntelliSense becomes available with the first character you type. Also note that the drop-down window has two tabs on the bottom: one is optimized for the items that you are likely to want, while the other shows you everything that is available. In addition, IntelliSense works with multiword commands. For example, if you type Exit and a space, IntelliSense displays a drop-down list of keywords that could follow Exit. Other keywords that offer drop-down lists to present available options include Goto, Implements, Option, and Declare. In most cases, IntelliSense displays more tooltip information in the environment than in past versions of Visual Studio, and helps developers match up pairs of parentheses, braces, and brackets.

Figure 1.17 IntelliSense in action

1.17

Finally, note that IntelliSense is based on your editing context. While editing a file, you may reach a point where you are looking for a specific item to show up in IntelliSense, but when you repeatedly type slightly different versions, nothing appears. IntelliSense recognizes that you aren't in a method or you are outside of the scope of a class, so it removes items that are inappropriate for the current location in your source code from the list of items available from IntelliSense.

Code Expansion

Going beyond IntelliSense is code expansion. Code expansion recognizes that certain keywords are consistently associated with other lines of code. At the most basic level, this occurs when you declare a new Function or Sub: Visual Studio automatically inserts the End Sub or End Function line once you press Enter. Essentially, Visual Studio is expanding the declaration line to include its matching endpoint.

However, true code expansion goes further than this. With true code expansion, you can type a keyword such as For, ForEach, Select, or any of a number of Visual Basic keywords. If you then use the Tab key, Visual Studio will attempt to recognize that keyword and insert the block of code that you would otherwise need to remember and type yourself. For example, instead of needing to remember how to format the control values of a Select statement, you can just type the first part of the command Select and then press Tab to get the following code block:

Select Case VariableName
    Case 1
    Case 2
    Case Else
End Select

Unfortunately, this is a case where just showing you the code isn't enough. That's because the code that is inserted has active regions within it that represent key items you will customize. Thus, Figure 1.18 provides a better representation of what is inserted when you expand the Select keyword into a full Select Case statement.

Figure 1.18 Expanded Select Case statement

1.18

When the block is inserted, the editor automatically positions your cursor in the first highlighted block—VariableName. When you start typing the name of the variable that applies, the editor automatically clears that static VariableName string, which is acting as a placeholder. Once you have entered the variable name you want, you can just press Tab. At that point the editor automatically jumps to the next highlighted item. This capability to insert a block of boilerplate code and have it automatically respond to your customization is extremely useful. However, this code isn't needed in the sample. Rather than delete, it use the Ctrl+Z key combination to undo the addition of this Select statement in your code.

Code expansion enables you to quickly shift between the values that need to be customized, but these values are also linked where appropriate, as in the next example. Another code expansion shortcut creates a new property in a class. Position the cursor above your generated event handler to add a custom property to this form. Working at the class level, when you type the letters prop and then press the Tab key twice, code expansion takes over. After the first tab you'll find that your letters become the word “Property,” and after the second tab the code shown in Figure 1.19 will be added to your existing code. On the surface this code is similar to what you see when you expand the Select statement. Note that although you type prop, even the internal value is part of this code expansion. Furthermore, Visual Basic implemented a property syntax that is dependent on an explicit backing field. For simplicity, you may not use a backing field on every property, but it's good to see how this expansion provides the more robust backing-field-supported syntax for a property.

Figure 1.19 Editing a newly created property in Visual Studio

1.19

Notice how the same value String in Figure 1.19 is repeated for the property. The value you see is the default. However, when you change the first such entry from String to Integer, Visual Studio automatically updates all three locations because it knows they are linked. Using the code shown in Figure 1.19, update the property value to be m_Count. Press Tab and change the type to Integer; press Tab again and label the new property Count. Keep in mind this is a temporary state—once you've accepted this template, the connections provided by the template are lost. Once you are done editing, you now have a simple property on this form for use later when debugging.

The completed code should look like the following block:

    Private m_Count As Integer
    Public Property Count() As Integer
        Get
            Return m_Count
        End Get
        Set(ByVal value As Integer)
            m_Count = value
        End Set
    End Property

This capability to fully integrate the template supporting the expanded code with the highlighted elements, helping you navigate to the items you need to edit, makes code expansion such a valuable tool.

Code Snippets

With a click of your mouse you can browse a library of code blocks, which, as with code expansion, you can insert into your source file. However, unlike code expansion, these snippets aren't triggered by a keyword. Instead, you right-click and—as shown in Figure 1.20—select Insert Snippet from the context menu. This starts the selection process for whatever code you want to insert.

Figure 1.20 Preparing to insert a snippet

1.20

The snippet library, which is installed with Visual Studio, is fully expandable, as discussed later in this chapter. Snippets are categorized by the function on which each is focused. For example, all the code you can reach via code expansion is also available as snippets, but snippets go well beyond that list. There are snippet blocks for XML-related actions, for operating system interface code, for items related to Windows Forms, and, of course, a lot of data-access-related blocks. Unlike code expansion, which enhances the language in a way similar to IntelliSense, code snippets are blocks of code focused on functions that developers often write from scratch.

As shown in Figure 1.21, the insertion of a snippet triggers the creation of a placeholder tag and a context window showing the categories of snippets. Each of the folders can contain a combination of snippet files or subdirectories containing still more snippet files. In addition, Visual Studio includes the folder My Code Snippets, to which you can add your own custom snippet files.

Figure 1.21 Selecting the category of snippet

1.21

Selecting a folder enables you to select from one of its subfolders or a snippet file. Once you select the snippet of interest, Visual Studio inserts the associated code into your source file. Figure 1.22 shows the result of adding an operating system snippet to some sample code. The selected snippet was Windows System—Logging, Processes, Registry, Services ⇒ Windows—Event LogsRead Entries Created by a Particular Application from the Event Log.

Figure 1.22 Viewing the snippet code

1.22

As you can see, this code snippet is specific to reading the Application Log. This snippet is useful because many applications log their errors to the Event Log so that they can be reviewed either locally or from another machine in the local domain. The key, however, is that the snippet has pulled in the necessary class references, many of which might not be familiar to you, and has placed them in context. This reduces not only the time spent typing this code, but also the time spent recalling exactly which classes need to be referenced and which methods need to be called and customized.

Finally, it is also possible to shortcut the menu tree. Specifically, if you know the shortcut for a snippet, you can type that and then press Tab to have Visual Studio insert the snippet. For example, typing evReadApp followed by pressing Tab will insert the same snippet shown in Figure 1.22.

Tools such as code snippets and especially code expansion are even more valuable when you work in multiple languages. Keep in mind, however, that Visual Studio isn't limited to the features that come in the box. It's possible to extend Visual Studio not only with additional controls and project templates, but also with additional editing features. Once again this code was merely for demonstration, and you shouldn't keep this snippet within your event handler.

Code Regions

Source files in Visual Studio allow you to collapse blocks of code. The idea is that in most cases you can reduce the amount of onscreen code, which seems to separate other modules within a given class, by collapsing the code so it isn't visible; this feature is known as outlining. For example, if you are comparing the load and save methods and you have several other blocks of code, then you can effectively “hide” this code, which isn't part of your current focus.

By default, there is a minus sign next to every method (sub or function). This makes it easy to hide or show code on a per-method basis. If the code for a method is hidden, the method declaration is still shown and has a plus sign next to it indicating that the body code is hidden. This feature is very useful when you are working on a few key methods in a module and you want to avoid scrolling through many screens of code that are not relevant to the current task.

It is also possible to create custom regions of code so you can hide and show portions of your source files. For example, it is common to see code where all of the properties are placed in one region, and all of the public methods are placed in another. The #Region directive is used for this within the IDE, though it has no effect on the actual application. A region of code is demarcated by the #Region directive at the beginning and the #End Region directive at the end. The #Region directive that is used to begin a region should include a description that appears next to the plus sign shown when the code is minimized.

The outlining enhancement was in part inspired by the fact that the original Visual Studio designers generated a lot of code and placed all of this code in the main .vb file for that form. It wasn't until Visual Studio 2005 and partial classes that this generated code was placed in a separate file. Thus, the region allowed the generated code section to be hidden when a source file was opened.

Being able to see the underpinnings of your generated UI does make it is easier to understand what is happening, and possibly to manipulate the process in special cases. However, as you can imagine, it can become problematic; hence the #Region directive, which can be used to organize groups of common code and then visually minimize them.

Visual Studio developers can also control outlining throughout a source file. Outlining can be turned off by selecting Edit ⇒ Outlining ⇒ Stop Outlining from the Visual Studio menu. This menu also contains some other useful functions. A section of code can be temporarily hidden by highlighting it and selecting Edit ⇒ Outlining ⇒ Hide Selection. The selected code will be replaced by ellipses with a plus sign next to it, as if you had dynamically identified a region within the source code. Clicking the plus sign displays the code again.

Customizing the Event Handler

At this point you should customize the code for the button handler, as this method doesn't actually do anything yet. Start by adding a new line of code to increment the property Count you added to the form earlier. Next, use the System.Windows.MessageBox class to open a message box and show the message indicating the number of times the Hello World button has been pressed. Fortunately, because that namespace is automatically imported into every source file in your project, thanks to your project references, you can reference the MessageBox.Show method directly. The Show method has several different parameters and, as shown in Figure 1.23, not only does the IDE provide a tooltip for the list of parameters, it also provides help regarding the appropriate value for individual parameters.

Figure 1.23 Using IntelliSense to the fullest

1.23

The completed call to MessageBox.Show should look similar to the following code block. Note that the underscore character is used to continue the command across multiple lines. In addition, unlike previous versions of Visual Basic, for which parentheses were sometimes unnecessary, in .NET the syntax best practice is to use parentheses for every method call:

     Private Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
         Count += 1
         MessageBox.Show("Hello World shown " + Count.ToString() + " times.",
                "Hello World Message Box",
                 MessageBoxButton.OK,
                 MessageBoxImage.Information)

End Sub

Once you have entered this line of code, you may notice a squiggly line underneath some portions of your text. This occurs when there is an error in the line you have typed. The Visual Studio IDE works more like the latest version of Word—it highlights compiler issues while allowing you to continue working on your code. Visual Basic is constantly reviewing your code to ensure that it will compile, and when it encounters a problem it immediately notifies you of the location without interrupting your work.

Reviewing the Code

The custom code for this project resides in two source files. The first is the definition of the window, MainWindows.xaml. Listing 1.1 displays the final XAML for this file. Note your Grid.RowDefinition probably varies from what you'll see in the final listing.

Listing 1.1: XAML for main window—MainWindow.xaml

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Pro VB 2012" Height="350" Width="525">
    <Grid Background="Black">
        <Grid.RowDefinitions>
            <RowDefinition Height="42"/>
            <RowDefinition Height="139*"/>
        </Grid.RowDefinitions>
        <Button Content="Run Sample" HorizontalAlignment="Left" 
Margin="37,10,0,0" VerticalAlignment="Top" 
Width="100" Height="22" Click="Button_Click_1"/>
        <ScrollViewer Margin="0,0,0,0" Grid.Row="1">
            <TextBox Name="TextBoxResult" TextWrapping="Wrap" />
        </ScrollViewer>
    </Grid>
</Window>

This XAML reflects the event handler added for the button. The handler itself is implemented in the accompanying code-behind file MainWindow.xaml.vb. That code is shown in Listing 1.2 and contains the custom property and the click event handler for your button.

Listing 1.2: Visual Basic code for main window—MainWindow.xaml.vb

Class MainWindow 
    Private m_Count As Integer
    Public Property Count() As Integer
        Get
            Return m_Count
        End Get
        Set(ByVal value As Integer)
            m_Count = value
        End Set
    End Property

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
        Count += 1
        MessageBox.Show("Hello World shown " + Count.ToString() + " times.",
               "Hello World Message Box",
                MessageBoxButton.OK,
                MessageBoxImage.Information)
    End Sub
End Class

At this point, you can test the application, but to do so let's first look at your build options.

Building Applications

For this example, it is best to build your sample application using the Debug build configuration. The first step is to ensure that Debug is selected as the active configuration. As noted earlier in this chapter around Figure 1.7, you'll find the setting available on your project properties. It's also available from the main Visual Studio display as a drop-down list box that's part of the Standard Toolbar. Visual Studio provides an entire Build menu with the various options available for building an application. There are essentially three options for building applications:

1. Build—This option uses the currently active build configuration to build the project or solution, depending upon what is available.
2. Rebuild—By default for performance, Visual Studio attempts to leave components that haven't changed in place. However, in the past developers learned that sometimes Visual Studio wasn't always accurate about what needed to be built. As a result this menu item allows you to tell Visual Studio to do a full build on all of the assemblies that are part of your solution.
3. Clean—This does what it implies—it removes all of the files associated with building your solution.

The Build menu supports building for either the current project or the entire solution. Thus, you can choose to build only a single project in your solution or all of the projects that have been defined as part of the current configuration. Of course, anytime you choose to test-run your application, the compiler will automatically perform a compilation check to ensure that you run the most recent version of your code.

You can either select Build from the menu or use the Ctrl+Shift+B keyboard combination to initiate a build. When you build your application, the Output window along the bottom edge of the development environment will open. As shown in Figure 1.24, it displays status messages associated with the build process. This window should indicate your success in building the application.

Figure 1.24 Build window

1.24

If problems are encountered while building your application, Visual Studio provides a separate window to help track them. If an error occurs, the Task List window will open as a tabbed window in the same region occupied by the Output window (refer to Figure 1.24). Each error triggers a separate item in the Task List. If you double-click an error, Visual Studio automatically repositions you on the line with the error. Once your application has been built successfully, you can run it, and you will find the executable file located in the targeted directory. By default, for .NET applications this is the in subdirectory of your project directory.

Running an Application in the Debugger

As discussed earlier, there are several ways to start your application. Starting the application launches a series of events. First, Visual Studio looks for any modified files and saves those files automatically. It then verifies the build status of your solution and rebuilds any project that does not have an updated binary, including dependencies. Finally, it initiates a separate process space and starts your application with the Visual Studio debugger attached to that process.

When your application is running, the look and feel of Visual Studio's IDE changes, with different windows and button bars becoming visible (see Figure 1.25). Most important, and new to Visual Studio 2012, the bottom status bar goes from blue to orange to help provide a visual indicator of the change in status.

Figure 1.25 Stopped at a breakpoint while debugging

1.25

While your code remains visible, the IDE displays additional windows—by default, the Immediate Window appears as a new tabbed window in the same location as the Output Window. Others, such as the Call Stack, Locals, and Watch windows, may also be displayed over time as you work with the debugger. These windows are used by you, the real debugger, for reviewing the current value of variables within your code.

The true power of the Visual Studio debugger is its interactive debugging. To demonstrate this, with your application running, select Visual Studio as the active window. Change your display to the MainWindow.xaml.vb Code view (not Design view) and click in the border alongside the line of code you added to increment the count when the button is clicked. Doing this creates a breakpoint on the selected line (refer to Figure 1.25). Return to your application and then click the “Run Sample” button. Visual Studio takes the active focus, returning you to the code window, and the line with your breakpoint is now selected.

Visual Studio 2010 introduced a new window that is located in the same set of tabs as the Solution Explorer. As shown in Figure 1.25, the IntelliTrace window tracks your actions as you work with the application in Debug mode. Figure 1.26 focuses on this new feature available to the Ultimate edition of Visual Studio. Sometimes referred to as historical debugging, the IntelliTrace window provides a history of how you got to a given state.

Figure 1.26 IntelliTrace display at a breakpoint

1.26

When an error occurs during debugging, your first thought is likely to be “What just happened?” But how do you reproduce that error? As indicated in Figure 1.26, the IntelliTrace window tracks the steps you have taken—in this case showing that you had used the Run Code button a second time since the steps shown in Figure 1.26. By providing a historical trail, IntelliTrace enables you to reproduce a given set of steps through your application. You can also filter the various messages either by message type or by thread.

The ability to select these past breakpoints and review the state of variables and classes in your running application can be a powerful tool for tracking down runtime issues. The historical debugging capabilities are unfortunately only available in Visual Studio Ultimate, but they take the power of the Visual Studio debugger to a new level.

However, even if you don't have the power of historical debugging, the Visual Studio debugger is a powerful development ally. It is, arguably, more important than any of the other developer productivity features of Visual Studio. With the execution sitting on this breakpoint, it is possible to control every aspect of your running code. Hovering over the property Count, as shown in Figure 1.27, Visual Studio provides a debug tooltip showing you the current value of this property. This “hover over” feature works on any variable in your local environment and is a great way to get a feel for the different values without needing to go to another window.

Figure 1.27 Using a debug tooltip to display the current value of a variable

1.27

Windows such as Locals and Autos display similar information about your variables, and you can use these to update those properties while the application is running. However, you'll note that the image in Figure 1.27 includes a small pin symbol. Using this, you can keep the status window for this variable open in your Code view. Using this will allow you to see the information in the debug window update to show the new value of Count every time the breakpoint is reached.

This isn't the end of it. By clicking on the down arrows you see on the right-hand side of your new custom watch window, just below the pin, you can add one or more comments to your custom watch window for this value. You also have the option to unpin the initial placement of this window and move it off of your Code view display. Not only that, but the custom watch window is persistent in Debug mode. If you stop debugging and restart, the window is automatically restored and remains available until you choose to close it using the close button.

Next, move your mouse and hover over the parameter sender. This will open a window similar to the one for Count and you can review the reference to this object. However, note the small plus sign on the right-hand side, which if clicked expands the pop-up to show details about the properties of this object. As shown in Figure 1.28, this capability is available even for parameters like sender, which you didn't define. Figure 1.28 also illustrates a key point about looking at variable data. Notice that by expanding the top-level objects you can eventually get to the properties inside those objects. Within some of those properties on the right-hand side is a little magnifying glass icon. That icon tells you that Visual Studio will open the potentially complex value in any one of up to four visualization tool windows. When working with complex XML or other complex data, these visualizers offer significant productivity benefits by enabling you to review data.

Figure 1.28 Delving into sender and selecting a visualizer

1.28

Once you are at a breakpoint, you can control your application by leveraging the Debug buttons on the Standard toolbar. These buttons, shown in Figure 1.29, provide several options for managing the flow of your application. One of the main changes to Visual Studio 2012 is in fact the layout of the buttons and options visible within the IDE. This is one of those situations: in the past the debug buttons were grouped, but now there are several other buttons that sit between the various actions. From the left you see the Start/Continue button. Then a little further over in about the center of the image is the square that represents stop. It's colored red, and next to it is the icon to restart debugging. Finally, on the far right the last three buttons that use arrows represent Step-In, Step Over, and Step Out, respectively.

Figure 1.29 Toolbar buttons used in debugging

1.29

Step-In tells the debugger to jump to whatever line of code is first within the next method or property you call. Keep in mind that if you pass a property value as a parameter to a method, then the first such line of code is in the Get method of the parameter. Once there, you may want to step out. Stepping out of a method tells the debugger to execute the code in the current method and return you to the line that called the method. Thus, you could step out of the property and then step in again to get into the method you are actually interested in debugging.

Of course, sometimes you don't want to step into a method; this is where the Step-Over button comes in. It enables you to call whatever method(s) are on the current line and step to the next sequential line of code in the method you are currently debugging. The final button, Step-Out, is useful if you know what the code in a method is going to do, but you want to determine which code called the current method. Stepping out takes you directly to the calling code block.

Each of the buttons shown on the debugging toolbar in Figure 1.29 has an accompanying shortcut key for experienced developers who want to move quickly through a series of breakpoints.

Of course, the ability to leverage breakpoints goes beyond what you can do with them at runtime. You can also disable breakpoints that you don't currently want to stop your application flow, and you can move a breakpoint, although it's usually easier to just click and delete the current location, and then click and create a new breakpoint at the new location.

Visual Studio provides additional properties for managing and customizing breakpoints. As shown in Figure 1.30, it's also possible to add specific properties to your breakpoints. The context menu shows several possible options.

Figure 1.30 Customizing a breakpoint

1.30

More important, it's possible to specify that a given breakpoint should execute only if a certain value is defined (or undefined). In other words, you can make a given breakpoint conditional, and a pop-up window enables you to define this condition. Similarly, if you've ever wanted to stop, for example, on the thirty-seventh iteration of a loop, then you know the pain of repeatedly stopping at a breakpoint inside a loop. Visual Studio enables you to specify that a given breakpoint should stop your application only after a specified number of hits.

The next option is one of the more interesting options if you need to carry out a debug session in a live environment. You can create a breakpoint on the debug version of code and then add a filter that ensures you are the only user to stop on that breakpoint. For example, if you are in an environment where multiple people are working against the same executable, then you can add a breakpoint that won't affect the other users of the application.

Similarly, instead of just stopping at a breakpoint, you can also have the breakpoint execute some other code, possibly even a Visual Studio macro, when the given breakpoint is reached. These actions are rather limited and are not frequently used, but in some situations this capability can be used to your advantage.

Note that breakpoints are saved when a solution is saved by the IDE. There is also a Breakpoints window, which provides a common location for managing breakpoints that you may have set across several different source files.

Finally, at some point you are going to want to debug a process that isn't being started from Visual Studio—for example, if you have an existing website that is hosting a DLL you are interested in debugging. In this case, you can leverage Visual Studio's capability to attach to a running process and debug that DLL. At or near the top (depending on your settings) of the Tools menu in Visual Studio is the Attach to Process option. This menu option opens a dialog showing all of your processes. You could then select the process and have the DLL project you want to debug loaded in Visual Studio. The next time your DLL is called by that process, Visual Studio will recognize the call and hit a breakpoint set in your code. This is covered in more detail in Chapter 16.

Other Debug-Related Windows

As noted earlier, when you run an application in Debug mode, Visual Studio can open a series of windows related to debugging. Each of these windows provides a view of a limited set of the overall environment in which your application is running. From these windows, it is possible to find things such as the list of calls (stack) used to get to the current line of code or the present value of all the variables currently available. Visual Studio has a powerful debugger that is fully supported with IntelliSense, and these windows extend the debugger.

Output

Recall that the build process puts progress messages in this window. Similarly, your program can also place messages in it. Several options for accessing this window are discussed in later chapters, but at the simplest level the Console object echoes its output to this window during a debug session. For example, the following line of code can be added to your sample application:

Console.WriteLine("This is printed in the Output Window")

This line of code will cause the string “This is printed in the Output Window” to appear in the Output window when your application is running. You can verify this by adding this line in front of the command to open the message box. Then, run your application and have the debugger stop on the line where the message box is opened. If you check the contents of the Output window, you will find that your string is displayed.

Anything written to the Output window is shown only while running a program from the environment. During execution of the compiled module, no Output window is present, so nothing can be written to it. This is the basic concept behind other objects such as Debug and Trace, which are covered in more detail in Chapter 6.

Call Stack

The Call Stack window lists the procedures that are currently calling other procedures and waiting for their return. The call stack represents the path through your code that leads to the currently executing command. This can be a valuable tool when you are trying to determine what code is executing a line of code that you didn't expect to execute.

Locals

The Locals window is used to monitor the value of all variables currently in scope. This is a fairly self-explanatory window that shows a list of the current local variables, with the value next to each item. As in previous versions of Visual Studio, this display enables you to examine the contents of objects and arrays via a tree-control interface. It also supports the editing of those values, so if you want to change a string from empty to what you thought it would be, just to see what else might be broken, then feel free to do so from here.

Watch Windows

There are four Watch windows, numbered Watch 1 to Watch 4. Each window can hold a set of variables or expressions for which you want to monitor the values. It is also possible to modify the value of a variable from within a Watch window. The display can be set to show variable values in decimal or hexadecimal format. To add a variable to a Watch window, you can either right-click the variable in the Code Editor and then select Add Watch from the pop-up menu, or drag and drop the variable into the watch window.

Immediate Window

The Immediate window, as its name implies, enables you to evaluate expressions. It becomes available while you are in Debug mode. This is a powerful window, one that can save or ruin a debug session. For example, using the sample from earlier in this chapter, you can start the application and press the button to stop on the breakpoint. Go to the Immediate window and enter ?TextBoxResult.Text = “Hello World” and press Enter. You should get a response of false as the Immediate window evaluates this statement.

Notice the preceding ?, which tells the debugger to evaluate your statement, rather than execute it. Repeat the preceding text but omit the question mark: TextBoxResult.Text = “Hello World”. Press F5 or click the Run button to return control to your application, and notice the text now shown in the window. From the Immediate window you have updated this value. This window can be very useful if you are working in Debug mode and need to modify a value that is part of a running application.

Autos

Finally, there is the Autos window. The Autos window displays variables used in the statement currently being executed and the statement just before it. These variables are identified and listed for you automatically, hence the window's name. This window shows more than just your local variables. For example, if you are in Debug mode on the line to open the MessageBox in the ProVB_VS2012 sample, then the MessageBox constants referenced on this line are shown in this window. This window enables you to see the content of every variable involved in the currently executing command. As with the Locals window, you can edit the value of a variable during a debug session.

Reusing Your First Windows Form

As you proceed through the book and delve further into the features of Visual Basic, you'll want a way to test sample code. Chapter 2 in particular has snippets of code which you'll want to test. One way to do this is to enhance the ProVB_VS2012 application. Its current use of a MessageBox isn't exactly the most useful method of testing code snippets. So let's update this application so it can be reused in other chapters and at random by you when you are interested in testing a snippet.

At the core you'll continue to access code to test where it can be executed from the ButtonTest Click event. However, instead of using a message box, you can use the resulting text box to hold the output from the code being tested.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset