2.1 Text Editor

Visual Studio .NET provides a text editor that provides the basic source code editing facilities that are common to all languages. Each language service can extend the text editor to provide language-specific features. (See Chapter 10 for information about how language services extend VS.NET.) As well as supplying the basic text editing services, the editor also has hooks that allow language services to provide advanced features, such as IntelliSense and automatic formatting. Even though the exact way in which these services work is language-specific, the IDE provides the basic framework so that the behavior is as consistent as possible across languages.

You can configure the way the text editor behaves for each language. When a particular language takes advantage of a standard editor feature such as IntelliSense, you will be able to configure that feature's behavior either globally or, if you prefer, on a per-language basis. Most languages also have their own unique configuration options. You can edit all of these options by selecting Tools Options and then selecting the Text Editor folder in the lefthand pane of the Options dialog box. As Figure 2-1 shows, you will see a list of supported languages. Appendix D describes all of the available options.

Figure 2-1. The Text Editor Options dialog box

Visual Studio .NET provides many coding aids to make editing your source code easier. The following sections describe each of these features.

2.1.1 IntelliSense

Visual Studio .NET provides a number of context-sensitive autocompletion features, collectively referred to as IntelliSense. VS.NET relies on the language service for the file you are editing to work out which symbols are in scope and uses this to show pop-up lists of suggestions, to show information in ToolTips or to autocomplete your text.

Four varieties of assistance are offered by IntelliSense. All of them can be invoked manually from the Edit IntelliSense menu, but IntelliSense usually works automatically (unless you've disabled it). However, it can sometimes be useful to give it a kick, because in some situations, it doesn't operate automatically when you need it. (The most common example being when you want to bring up a list of members in scope at function scope. Many people use the trick of typing in this. to bring up a list of members, but it is easier to use the shortcuts once you know about them.) The four IntelliSense commands are:

List Members (Ctrl-J)

List Members displays a list of available members. The exact contents of the list are determined by the cursor position. If the cursor is placed after a variable name followed by a member access operator (. in VB.NET and C#, and either . or -> in C++), it will list the members of that variable's type. If the cursor is just on some whitespace inside a function, it will list all available variables, types, and members currently in scope.

You can find the member you want in the list by typing in the first few letters of the member until the member is highlighted or by selecting the member with the mouse or arrow keys. When available, VS.NET will display brief documentation for the currently selected item in a ToolTip next to the list. Once you have highlighted the member you would like to use, VS.NET can enter the member name into your code for you. Either double-click on the item or just type any character that would not be allowed in an identifier (e.g., any of (, ., ;, Space, or Enter). Alternatively, you can execute the Complete Word command (see later).

The List Members command executes automatically if you type in a variable name followed by the character for member access or object dereferencing (usually ., ->, or ::). However, the list will disappear if you start doing something else (e.g., you click to move the cursor elsewhere) so this shortcut is useful for bringing it back. Also, if you select the wrong item by accident, pressing Ctrl-J will reopen the list with your current selection highlighted, allowing you to move to the item you meant to select.

Parameter Info (Ctrl-Shift-Space)

This command displays the names and types of the parameters needed to call a method, along with the method's return type. This command works only if the cursor is inside the parentheses of a method call. (The command is invoked automatically when you type the open parenthesis for a method call.)

Quick Info (Ctrl-K, Ctrl-I)

The Quick Info command displays the complete declaration for any identifier in your code and, where available, a documentation summary. (This is the same information that will be shown if you move the mouse over an identifier and hover.) The declaration is displayed in a ToolTip-style box. If Quick Info is not autoenabled, hovering the mouse will not work, and you will need to execute this command manually to make the pop up display. (Even if Quick Info is autoenabled, it is still often useful to be able to invoke it without reaching for the mouse. You will also need to invoke the command manually if you need it while debuggingin debug mode, the default behavior when you hover over an item is to display its value instead of its quick info.)

Complete Word (Alt-Right Arrow or Ctrl-Space)

Complete Word will complete whatever symbol is currently selected in the IntelliSense member list. If the list is not currently open, IntelliSense will work out whether the letters typed so far unambiguously refer to a particular member. If they do, it will complete the member. If, however, the text already present is ambiguous (and the member list is not already open), it will display the member list. For example, if the text editor had the text Console.W, the W might be expanded to either Write or WriteLine. Since this is ambiguous, it will open the member list to let you choose the one you mean. If you have VS.NET 2003 and are using C# or J#, you can enable the "Preselect most frequently used members" option. (This setting can be found in the options dialog, which can be opened using Tools Options. On the left of the dialog, expand the Text Editor category, and then under either C# or Visual J# select the Formatting item.) This will cause VS.NET to highlight the item you use most often. Otherwise, it will just choose the first matching itemWrite in this case.

Some other autocompletion features are provided by the C# language service. Automatic skeleton insertion for interfaces and virtual methods is described later in this chapter (in the Section 2.1.5 section). Help is also provided with event handlers. (This feature is not available in VS.NET 2002.) If you write the += operator after an event member name (e.g., myButton.Click +=), a tooltip will appear offering to add code to create an appropriate delegate if you press Tab. If you go ahead and press the Tab key, it adds the appropriate code (e.g., new EventHandler(myButton_Click);). At this point a second tooltip will appear, offering to create a skeleton function whose signature matches the delegate and with a name matching its suggestion in the first completion. (So in this case, pressing Tab a second time would add a function called myButton_Click, with the correct signature for a Click event handler.)

2.1.2 C# Documentation

The C# programming language lets you put special comments in the source code that can be used to generate documentation. These comments must begin with three slashes instead of the normal two and must be in an XML-based format. The XML is typically converted into HTML-based documentation for your solution. However, the XML can also be used by IntelliSense to provide pop-up documentation for types and their members. It uses the summary element for this, so you should always keep that part fairly succinct. The following code snippet shows a typical example of this documentation:

/// <summary>

/// The main entry point for the application.

/// </summary>


static void Main(  )

If you type three slashes into the source editor in a C# file (or /**, which is the other way of indicating that a comment contains XML documentation), you will find that Visual Studio .NET automatically provides an XML skeleton for your documentation. This will always include a summary element, but if you put the comment before a method, VS.NET will also add elements for each parameter and for the return type. VS.NET also provides IntelliSense pop ups for the XML, telling you which elements are supported for the item you are documenting. (A complete description of the supported elements can be found in C# in a Nutshell (O'Reilly and Associates) and also in the C# Language Specification in the MSDN Library.)

IntelliSense will automatically use this documentation if it is present, but you must explicitly ask for HTML documentation to be built if you want it. You do this using Tools Build Comment Web Pages.

The style of documentation produced by the Build Comment Web Pages menu item is different from the style used by VS.NET's own documentation. If you would like to generate documentation that looks similar to the documentation for the .NET Framework Class Libraries, you can download a free program from http://ndoc.sourceforge.net.com that will generate either HTML files or compiled help files that look just like the .NET documentation.

2.1.3 Beautifier

VS.NET can reformat the currently selected portion of a file. The exact behavior of this feature is controlled by the language service. This feature is not available for certain file types (such as text files).

To invoke this feature, first select the region of text you would like to reformat (if you want to reformat the entire file, use Ctrl-A or Edit Select All). Then select Edit Advanced Format Selection (Ctrl-K, Ctrl-F). This will reformat the selected area. Most languages that support this feature allow the way in which reformatting occurs to be controlledsee Appendix F for details of the relevant settings.

2.1.4 Navigation Bar

A navigation bar is available for five different languages: C#, J#, C++, VB.NET, and HTML/XML. In C#, J#, and C++, the navigation bar is just a navigation aidyou can use it to navigate to specific type and member declarations. However, with VB.NET and HTML, the navigation bars have slightly more functionality.

The navigation bar allows you add event handlers in VB.NET and HTML files. If you are editing a class, form, or page that contains event sources, these will appear in the lefthand list. If you select one, the righthand list will show all of the events it provides. Selecting one of these adds a skeleton event handler.

The navigation bar is very fussy about the HTML structure. If your HTML is not clean, the navigation bar will not work correctly.

With VB.NET, the navigation bar also allows you to add new code as well as navigating to existing code. In VB.NET, if you select your class in the lefthand drop-down list, the righthand list will not only contain your class's members, it will also show some methods you have not yet implemented. The list will contain overridable methods from your base class, along with any members of interfaces your class implements. When you pick a method that you have not yet implemented, the editor adds a skeleton implementation (just the Sub or Function declaration and the corresponding End Sub or End Function).

2.1.5 Class View

The class view provides a way of navigating within a solution. You can display the class view with View Class View (Ctrl-Shift-C). The class view shows a tree view of the types declared in your source files. In a multiproject solution, the types will be grouped by project.

When you expand a project in the class view, you will see all of the namespaces that the project defines, along with any classes that are in the default namespace. As you expand the tree view, you will see types and their members. If you double-click on any item in the tree, the cursor will go to its definition. You can also navigate in reverseyou can right-click in the text editor and select Synchronize Class View. This will show the Class View pane and will select the node corresponding to whichever item the cursor was over.

In both C# and C++, you can also use the Class View pane to generate skeleton implementations for overridable members from base types, as well as for interface members. If you expand any type that you have defined, its first node will be labeled Bases and Interfaces. If you expand that node, you will see your class's base type, along with any interfaces that it implements. If you find an overridable member of the base type (or any member of an interface) that you would like to implement, you can right-click on that member and select Add Override (Ctrl-Alt-Insert). This will add a skeleton for that member to your source file. You can also add skeletons for all members of an interface in one step: expand the Bases and Interfaces node, select the interface you require, right-click, and select Add Implement Interface....

Visual Studio .NET 2003 introduced new ways of generating skeleton implementations without using the class view. When you add an interface to the class's interface list in the text editor, a ToolTip appears offering to generate the stubs for you if you press the Tab key. And for overriding methods in the base class, simply typing in override anywhere in the class will bring up an IntelliSense pop up showing all overridable methodsif you select one of these, VS.NET will generate a skeleton implementation. But for VS.NET 2002, the class view is the only way to generate skeletons.

Another useful feature of the class view is that it can be customized. In a large project, there are likely to be a substantial number of classes. However, you may well be working with only a small subset of these at any given time. Rather than having to scroll through the tree to find the few classes you are interested in, you can create a new folder in the class view that contains just the items you wish to see. You create new folders with Project New Folder. You can add as many folders as you like. Folders can contain types, namespaces, or even individual membersjust drag them in there from their current place in the tree view. You can delete a type by highlighting it and pressing the Delete key. You can see an example of a custom folder containing a namespace, a type, and an individual member at the top of Figure 2-2.

Figure 2-2. Customized Class View folder

Custom class view folders have no impact on the output of the solutionthey merely change the way in which it is presented in VS.NET. Because of this, custom folder settings are not stored in the .sln file. Information that affects only the way in which VS.NET shows the project are typically held in per-user files, so custom folders settings are stored in the .suo file. This means that custom folders will not be saved into source control. (.suo files are not checked in by default, and it is not a good idea to check in user-specific IDE configuration files in any case.) You should therefore avoid relying on them to convey important information in team projects. (For example, do not rely on custom class view folders as part of your code documentation strategy.)

2.1.6 Navigation and Bookmarks

VS.NET provides a number of additional ways to navigate through your source code files. The View Navigate Backward (CTRL+-) and View Navigate Forward commands are like Undo and Redo commands for navigationas you are moving from file to file, and within a file itself, the editor remembers your location when you execute certain commands. (Not all commands are remembered, as otherwise the editor would have to remember every single editing keystroke or command.) These commands include searches, Go To Line (Ctrl-G), Beginning of Document (Ctrl-Home), End of Document (Ctrl-End), Pasting Text, and Go To Definition commands.

Bookmarks provide another useful navigation aid. You can add a bookmark to any line of source code by placing the cursor on that line and selecting Edit Bookmarks Toggle Bookmark (Ctrl-K, Ctrl-K). It is easy to see when a line has been bookmarked, as there will be a visual marker in the indicator margin (unless you have turned the indicator margin off). You can then use the commands under Edit Bookmarks to navigate back and forth between the different bookmarks you have placed in your source files, the most useful being Next Bookmark (Ctrl-K, Ctrl-N) and Previous Bookmark (Ctrl-K, Ctrl-P).

Bookmarks are saved when you close a solution. However, when you close an individual file, VS.NET discards any bookmarks you have placed in that file.

2.1.7 Outlining and Regions

The main language services (VB.NET, C#, J#, and C++) provide the text editor with outlining information for your source code. When outlining is enabled, VS.NET uses this to show markers in the lefthand margin of the text editor that delineate sections of your source code. The editor marks the start of a section by a minus (-) symbol inside a small square. It shows the extent of the section with a vertical gray line ending with a small horizontal tick.

Sections are frequently nesteda namespace will have a section, as will each class it contains and the members of those classes. In this case you will see the vertical gray line carrying on beyond the tick that marks the end of the nested section, as you can see in Figure 2-3 at the end of the section for the constructor.

These sections of code can be expanded and contracted, allowing you to hide sections of source code that you are not currently working on, thus making more effective use of your screen real estate. In Figure 2-3, you can see some sections of the source code that are hidden (like the using section) and some sections that are open (the code inside of the namespace declaration). When a section is hidden, it is represented by a plus (+) symbol in a square. The section can be unhidden by clicking on the +. Some text will be shown inside a box in the main part of the editor window next to the + to represent what is contained in the hidden section. The text shown will depend on the type of sectionfor example, in Figure 2-3, the using section appears as three periods, and the comment section appears as /**/. Hidden functions just show the function declaration. For #region sections (described later in this section), arbitrary text may be shown.

If you want to see the code contained in a hidden section without expanding it, you can hover the mouse over it. A ToolTip containing the hidden source code (or as much of the source code as will fit on the screen) will appear.

Figure 2-3. Outlined sections of code

One of the hidden sections in Figure 2-3 appears as the text "Component Designer generated code". This is an example of a section created with the #region keyword. (This particular section was added, unsurprisingly, by the component designer.) The language service decides where the outline sections should be placed, and they are usually based upon language constructs. But in VB.NET, C#, and J#, you can add extra sections using the #region and #endregion keywords (#Region and #End Region in VB.NET). You can place a string next to the opening directive, and this will be displayed in the box when the outlined section is hidden. Figure 2-4 shows how the region at the bottom of Figure 2-3 looks when it is expandedit is now clear how VS.NET knew what text to display when the section was hidden.

When a Visual Studio .NET designer generates code, it usually places it inside a #region directive. The main reason for this is that it discourages people from editing it by accidentregions are hidden by default. (You can change this default, though, as discussed in Appendix F.)

Figure 2-4. The #region directive expanded

The commands for outlining are found under Edit Outlining. The most useful command is Toggle Outlining Expansion (Ctrl-M, Ctrl-M)if the cursor is inside a section that is not currently hidden, VS.NET will hide it. If the cursor is over a hidden section, VS.NET will expand it. Also, Collapse to Definitions (Ctrl-M, Ctrl-O) will hide all members, and Toggle All Outlining (Ctrl-M, Ctrl-L) will expand any collapsed sections in the file. If there are no collapsed sections in the file, it collapses everything.

Although C++ provides outlining, it is missing a few features. It does not support the #region directive. Also, if you turn outlining off for a C++ file, the only way to restore it is to close and reopen the file, whereas in C#, J#, and VB.NET you can simply use Edit Outlining Start Outlining. Also, with C#, J#, and VB.NET, you can have outlining turned off in the language setting for the text editor and still turn it back on for individual files (also using the Start Outlining command), but if you turn off outlining in the C++ settings, you cannot turn it back on for a single file.

2.1.8 Text and the Toolbox

The Toolbox (View Toolbox) is used most often for visual editing (see the later section on designers, Section 2.4). But it can also be used as a place to keep useful chunks of text. You can select any section of source code, then drag the selection onto the Toolbox. (You can do this on any of the different tabs of the Toolboxeither the standard tabs or tabs you have added yourself.) Each time you do this, a new item will appear on the Toolbox. You can then move to another part of the same file or a different file and drag the item off the Toolbox and back into the editor where you would like it to be placed. This will create a copy of the original text. If you regularly need to insert pieces of boilerplate such as a standard comment header, this can be a great time-saver. To remove a text block from the Toolbox, right-click the text block and select Delete.

2.1.9 Clipboard Ring

Another section of the Toolbox that can be used for text editing is the Clipboard Ring tab. The clipboard ring holds the value of the last 12 copy or cut operations, and these are all displayed on the Clipboard Ring Toolbox tab. In fact, you don't need to use the Toolbox to take advantage of the clipboard ringyou can cycle through the items in the ring by pressing Ctrl-Shift-V until the text that you want appears in the text editor. Once you have found the item you want from the ring, it moves to the top of the ring. This means that if you want to paste it in again somewhere else, you only need to press Ctrl-V next time.

2.1.10 TaskList Comments

When you are editing a document, you may wish to leave comments in your code to remind yourself or others of work that still needs to be done. VS.NET can show a list of these kinds of comments along with their locations in the Task windowjust select View Show Tasks Comment. By default, it will look for comments that start with either TODO, HACK, or UNDONE, but you can also add your own custom tokens to the list using the Options dialog (Tools Options)underneath the Environment folder, select the TaskList property page.

Each token has one of three priorities assigned to it (Low, Normal, or High). The priority controls a visual cue that is displayed in the TaskList window and determines the order in which items will be displayed. The built-in tokens are all Normal by default, but with the exception of the TODO token, you can change the priority for these and your own tokens with the TaskList property page.

The following source code shows some comments that use this feature. (In addition to using the three standard comments, this example uses two custom comments.)

          //TODO:This code need optimizing

          public void Slow(  )



          //HACK:This method is a kludge

          public void BadCode(  )



          //UNDONE:Someone needs to finish this and it isn't me!

          public void NotDone(  )



          //MANAGERSEZ:We need this method

          public void Meaningless(  )



          //NOTTESTED:This code needs to be tested

          public void Crash(  )



This would produce a TaskList window like the one shown in Figure 2-5. Note that, by default, the TaskList shows only build errors. To enable the display of comments such as these, you must use the View Show Tasks menu. These comments will be shown only if you select All or Comment.

Figure 2-5. TaskList window

If you double-click on a task in the TaskList window, it will bring you to the line of code containing the comment. You can also cycle forward and backward through your undone tasks by selecting View Show Tasks Next Task (Ctrl-Shift-F12) or View Show Tasks Previous Task, respectively.