Smart Tags and Smart
|
IntelliSense
IntelliSense is the
As you type within the text editor, IntelliSense is the behind-the-scenes agent responsible for providing a list of code
We'll
Tip Attaching a schema to an XML document is beneficial from an IntelliSense perspective. The schema is used to further enhance the capabilities of the List Members function (see its section later in this chapter). There are many discrete pieces to IntelliSense that seamlessly work in conjunction with one another as you are writing code . Let's look at them one by one. Complete WordComplete Word is the basic time-saving kernel of IntelliSense. After you have typed enough characters for IntelliSense to recognize what you are trying to write, a guess is made as to the complete word you are in the process of typing. This guess is then presented to you within a list of possible alternatives (referred to as the completion list ) and can be inserted into the code editor with one keystroke. This is in contrast to your completing the word manually by typing all of its characters.
Figure 7.12 illustrates the process: Based on the context of the code and based on the characters typed into the editor, a list of possible words is displayed. One of these selections will be selected as the most
Figure 7.12. IntelliSense: Complete Word.
Note Complete Word takes the actual code context into account for a variety of different situations. For instance, if you are in the midst of keying in the exception type in a try/catch block, IntelliSense will display only exception types in the completion list. Likewise, typing an attribute will trigger a completion list filtered only for attributes; when you're implementing an interface, only interface types will be displayed, and so on. This IntelliSense feature is enabled for all sorts of content: Beyond C# and Visual Basic code, IntelliSense completion works for other files as well, such as HTML tags, CSS style attributes, .config files, and HTML script blocks, just to name a few. You can manually invoke Complete Word at any time by using the Ctrl+Spacebar or Alt+Right-arrow key combinations.
Quick
|
|
1. |
Type the name of a class (Ctrl+Space will give you the IntelliSense window with possible class
|
|
2. |
Type a period; this indicates to IntelliSense that you have finished with the type name and are now "scoped in" to that type's members.
|
|
3. |
The list of valid members will now be displayed. You can manually scroll through the list and select the desired member at this point, or, if you are well aware of the member you are trying to code, you can simply continue typing until IntelliSense has captured enough characters to select the member you are looking for.
|
|
4. |
Leverage Complete Word by pressing the Tab key to automatically insert the member into your line of code (thus saving you the typing effort).
|
This feature also operates in conjunction with Quick Info: As you select different members in the members list, a quick info pop-up will be displayed for that member.
Note
IntelliSense maintains a record of the most frequently used/selected members from the List Members and Complete Word functions. This record is used to help avoid displaying or selecting members that you have rarely, if ever, used for a given type.
Parameter Info, as its name implies, is designed to provide interactive guidance for the parameters needed for any given function call. This feature is
Parameter Info is initiated whenever you type an opening parenthesis after a function name. To see how this works, perform these steps:
|
1. |
Type the name of a function.
|
|
2. |
Type an open parenthesis.
|
|
3. |
A pop-up box will show the function signature. If there are multiple valid signatures (for example, multiple overloaded versions of this function), you can scroll through the different signatures by using the small up/down arrow cues.
|
|
4. |
After selecting the desired signature, you can start typing the actual parameters you want to pass in to the function.
|
|
5. |
As you type, the parameter info pop-up will continue coaching you through the parameter list by bolding the current parameter you are working on. As each successive parameter is highlighted, the definition for that parameter will appear.
|
In Figure 7.14, the second parameter for the Console object's SetWindowPosition function is currently being entered.
Code snippets are prestocked lines of code available for selection and insertion into the text editor. Each code snippet is referenced by a name referred to as its alias . Code snippets are used to automate what would normally be nonvalue-added, repetitive typing. You can create your own code snippets or use the default library of common code elements provided by Visual Studio.
You insert snippets by right-clicking at the intended insertion point within an open text editor window and then selecting Insert Snippet from the shortcut menu. This will launch the Code Snippet Inserter, which is a drop-down (or series of drop-
With C#, the Code Snippet Inserter is a single drop-down with all available aliases listed. Visual Basic provides an added feature here: Its inserter is actually categorized. To contrast the way the inserter works across these languages, let's look at some snapshots from the IDE.
First, let's look at how the inserter works with C#. Starting from a bare-bones class file, Figure 7.15 shows the results of expanding the
ctor
snippet into the window. The constructor code is left in place. It is syntactically correct and even has the correct constructor name (referring back to the class name). You can see that snippets can't do everything for youyou still have to write meaningful code inside the constructorbut snippets can eliminate
Now for Visual Basic: In Figure 7.16, a snippet designed to help manipulate the opacity of the Windows forms object is being selected. Note that these are folders displayed within the inserter's drop-down. They help to categorize and place an organizational hierarchy over the snippet library. The opacity snippet is located within the Windows Forms Applications folder. Selecting this folder will cause a placeholder to be displayed within the text editor window, and the inserter will now refresh to show only those snippets that have been placed in the Windows Forms Applications category.
Tip
A quick, alternate way to display the Code Snippet Inserter is to type a question mark and then press the Tab key. This works only with Visual Basic code documents.
The example here
Double-clicking the Create Transparent Windows Forms snippet will get you the code snippet you have been hunting for, but you still aren't done yet. In Figure 7.17, the snippet is selected, and the inserter has injected the template code into the Visual Basic code for you, but the inserter (at least in this case) wasn't
The snippet code has the form name filled in with a default, dummy name that is already highlighted. You merely have to start typing the form name you need, and it will replace the dummy name. The opacity value is also a
Tip
Snippets may have one or more placeholder values: fragments of code that you will want and probably need to change. You can cycle through each of the placeholder values by pressing the Tab key. When a placeholder is highlighted (in blue), you can start typing to replace the syntax with something that makes sense for your specific code context.
C# and XML documents have one additional style of code snippets that bears mentioning: Surround With snippets. Surround With snippets are still snippets at their
Using a Surround With snippet, you can stack enclosing text around a selection with the text editor. As an example, perhaps you have a few different class declarations that you would like to nest within a namespace. When you use the Surround With snippet, this is a simple two-step process: Highlight the class definitions and fire up the Code Snippet Inserter. This time, instead of selecting Insert Snippet from the shortcut menu, you select Surround With. The insert works the same way, but this time has applied the snippet (in this case, a namespace snippet) in a different fashion. Compare the before and after text shown in Figures 7.18 and 7.19.
Because code snippets are stored in XML files, you can create your own snippets quite easily. The key is to understand the XML schema that defines a snippet, and the best way to do that is to look at the XML source data for some of the snippets included with the IDE.
Snippets are stored on a per-language basis under the install directory for Visual Studio. For example, the Visual Basic snippets can be found, by default, in the folders under the C:\Program Files\Microsoft Visual Studio 8\Vb\Snippets directory. Although snippet files are XML, they carry a .Snippet extension.
Listing 7.1 provides the XML for the C# constructor snippet:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>ctor</Title>
<Shortcut>ctor</Shortcut>
<Description>Code snippet for constructor</Description>
<Author>Microsoft Corporation</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal Editable="false">
<ID>classname</ID>
<ToolTip>Class name</ToolTip>
<Function>ClassName()</Function>
<Default>ClassNamePlaceholder</Default>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[public $classname$ ()
{
$end$
}]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
|
The basic structure of this particular snippet declaration is described in Table 7.2. A more complete schema reference is available as a part of the Visual Studio MSDN help collection; it is located under Integrated Development Environment for Visual Studio, Reference, XML Schema References, Code Snippets Schema Reference.
|
XML Node |
Description |
|---|---|
|
<CodeSnippets> |
The parent element for all code snippet information. It references the specific XML namespace used to define snippets within Visual Studio 2005. |
|
<CodeSnippet> |
The root element for a single code snippet. This tag sets the format version information for the snippet (for the initial release of VS 2005, this should be set to 1.0.0.0). Although multiple CodeSnippet elements are possible within the parent <CodeSnippets> element, the convention is to place one snippet per file. |
|
<Header> |
A metadata container element for data that describes the snippet. |
|
<Title> |
The title of the code snippet. |
|
<Shortcut> |
Typically, the same as the title, this is the text that will appear in the code snippet insertion drop-downs. |
|
<Description> |
A description of the snippet. |
|
<Author> |
The author of the snippet. |
|
<SnippetTypes> |
The parent element for holding elements describing the snippet's type. |
|
<SnippetType> |
The type of the snippet: Expansion, Refactoring, or Surrounds With. You cannot create custom refactoring snippets. This property is really used to tell Visual Studio where the snippet can be inserted within the editor window: Expansion snippets insert at the current cursor position, while Surrounds With snippets get inserted before and after the code body identified by the current cursor position or selection. |
|
<Snippet> |
The root element for the snippet code. |
|
<Declarations> |
The root element for the literals and objects used by the snippet. |
|
<Literal> |
A string whose value can be interactively set as part of the snippet expansion process. The Editable attribute on this tag indicates whether the literal is static or editable. The ctor snippet is an example of one without an editable literal; contrast this with the form transparency snippet that you sawan example of a snippet with an editable literal that allows you to set the form name as part of the snippet insertion. |
|
<ID> |
A unique ID for the literal. |
|
<ToolTip> |
A ToolTip to display when the cursor is placed over the literal. |
|
<Function> |
The name of a function (see Table 7.3) to call when the literal receives focus. Functions are available only in C# snippets. |
|
<Default> |
The default string literal to insert into the editor. |
|
<Code> |
An element that contains the actual code to insert. |
The trick to writing a snippet is to understand how literals and variable replacement works. Say that you wanted to create a C# snippet that
// Code review of ContextToken. // Reviewer: Lars Powers // Date: 1/1/2006 // Approval: Approved
In this snippet, you need to treat four literals as variable; they can change each time the snippet is used: the class name, the reviewer's name, the date, and the approval. You can set them up within the declarations section like this:
<Declarations>
<Literal Editable="False">
<ID>classname</ID>
<ToolTip>Class name/type being reviewed</ToolTip>
<Function>ClassName()</Function>
<Default>ClassNameGoesHere</Default>
</Literal>
<Literal Editable="True">
<ID>reviewer</ID>
<ToolTip>Replace with the reviewer's name</ToolTip>
<Default>ReviewerName</Default>
</Literal>
<Literal Editable="True">
<ID>currdate</ID>
<ToolTip>Replace with the review date</ToolTip>
<Default>ReviewDate</Default>
</Literal>
<Literal Editable="True">
<ID>approval</ID>
<ToolTip>Replace with Approved or Rejected</ToolTip>
<Default>Approved</Default>
</Literal>
</Declarations>
Notice that you are actually calling a function to prepopulate the class name within the snippet. Functions are available only with C# (with a subset also available in J#) and are documented in Table 7.3. The rest of the literals rely on the developer to type over the placeholder value with the correct value.
|
Function |
Description |
|---|---|
|
GenerateSwitchCases( enumliteral ) |
Creates the syntax for a switch statement that includes a case statement for each value defined by the enumeration represented by enumliteral (C#/J#). |
|
ClassName() |
Inserts the name of the class containing the code snippet (C#/J#). |
|
SimpleTypeName( typename ) |
Takes the type name referenced by typename and returns the shortest name possible given the using statements in effect for the current code block. Example: SimpleTypeName(System.Exception) would return Exception if a using System statement is present (C#). |
|
CallBase( parameter ) |
Is useful when
|
You should also provide some basic header information for the snippet:
<Header>
<Title>review</Title>
<Shortcut>review</Shortcut>
<Description>Code review comment</Description>
<Author>L. Powers</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
At this point, the snippet is syntactically complete. Although this snippet is writing comments into the editor, the same exact process and structure would apply for emitting code into the editor. If you wanted to write a Surrounds With snippet, you would change the <SnippetType> to Surrounds With.
Now, you need to make Visual Studio aware of the snippet.
You can use Visual Studio's own XML editor to create the XML document and save it to a directory (a big bonus for doing so is that you can leverage IntelliSense triggered by the XML snippet schema to help you with your element names and relationships). The Visual Studio installer creates a default directory to place your custom snippets located in your My Documents folder: \My Documents\Visual Studio 2005\Code Snippets\VC#\My Code Snippets . If you place your XML template here, Visual Studio will automatically include your snippet for use.
The Code Snippets Manager is the central control dialog box for browsing the available snippets, adding new ones, or removing a snippet (see Figure 7.20). As you can see, the review snippet shows up under the My Code Snippets folder.
You can also opt to include other folders besides the standard ones. To do so, click on the Add button to enter additional folders for Visual Studio to use when displaying the list of snippets.
Figure 7.21 shows the results of the custom snippet.
Tip
Snippets can also be browsed and shared online (see Chapter 12, "The .NET Community Consuming and Creating Shared Code," for a discussion of online communities). A great way to further your understanding of code snippet structure and functions is to browse your way through the snippet files included in Visual Studio, as well as those created by the developer community as a whole.
Although this capability is technically not part of the official code snippet technology within Visual Studio, you can also store snippets of code in the Toolbox. First, select the text in the editor and then drag and drop it onto the Toolbox. You can then reuse this snippet at any time by dragging it back from the Toolbox into an open editor window.
Programming languages make use of parentheses, braces, brackets, and other delimiters to
Brace matching
refers to visual cues that the code editor uses to make you aware of your matching delimiters. As you type code into the editor, any time you enter a closing delimiter, the matching opening delimiter and the closing
Tip
You also can trigger brace matching simply by placing the cursor directly to the left of an opening delimiter or the right of a closing delimiter. If you are browsing through a routine
Although this feature is referred to as brace matching, it actually functions with the following delimiters:
Parentheses ()
Brackets [], <>
Quotation marks ""
Braces {}
In the case of C#, brace matching also works with the following keyword pairs (which
# region, #endregion
#if, #else, #endif
case, break
default, break
for, break, continue
if, else
while, break, continue
Certain IntelliSense features can be customized, on a per-language basis, within the Visual Studio Options dialog box. If you launch the Options dialog box (located under the Tools menu) and then navigate to the Text Editor node, you will find IntelliSense options confusingly
Figure 7.23 shows the IntelliSense editor Options dialog box for Visual C#.
Completion Lists in this dialog box refer to any of the IntelliSense features that facilitate autocompletion of code such as List Members and Complete Word. Table 7.4 itemizes the options available in this dialog box.
|
Option |
Effect |
|---|---|
|
Show Completion List After a Character Is Typed |
Checking this box causes the Complete Word feature to automatically run after a single character is typed in the editor window. |
|
Place Keywords in Completion Lists |
If this box is checked, language keywords will be displayed within the completion list. As an example, for C#, this would cause keywords such as class or string to be included in the completion list. |
|
Place Code Snippets in Completion Lists |
Checking this box will place code snippet alias names into any displayed completion lists. |
|
Committed by Typing the Following Characters |
This check box contains any of the characters that will cause IntelliSense to execute a completion action. In other words, typing any of the characters in this text box while a completion list is displayed will cause IntelliSense to insert the current selection into the editor window. |
|
Committed by Pressing the Space Bar |
Checking this box adds the space character to the list of characters that will fire a completion commit. |
|
IntelliSense Pre-selects Most Recently Used Members |
If this box is checked, IntelliSense will maintain and use a historical list of the most frequently used members for a given type. This MFU list is then used to preselect members in a completion list. |