March 1, 2021
Hot Topics:

Creating Simplified Code Generators in VS.NET, Part II

  • By Paul Kimmel
  • Send Email »
  • More Articles »

Using the VS.NET Automation Model

VS.NET exposes and extensive automation model that permits one to control almost every facet of the VS.NET IDE. You can get an idea of how comprehensive this object model is by exploring the VS.NET help topic ms-help://MS.VSCC.2003/MS.MSDNQTR.2003APR.1033/vsintro7/html/ vxgrfAutomationObjectModelChart.htm. You can navigate to this section of the help documentation by plugging the link into the VS.NET address bar.

I have made some assumptions about the state of VS.NET when the macro is run. The macro assumes that a source code module is open and the cursor is located where the code will be inserted. In coordination with these pre-conditions, then, we need to obtain the current source code document from the object model and insert our code at the current cursor location. The active document can be obtained from an instance of the design time environment. The class is called EnvDTE and the Singleton instance is named DTE. The DTE object represents the running IDE and already exists. All we need to do is interact with the DTE object. Listing 4 contains the rest of the code we will need to insert our generated property statement.

Listing 4: Inserting code into the active document.

Imports EnvDTE
Imports System.Diagnostics
Imports System

Public Module Generator

  Private Cr As String = Environment.NewLine

  Private mask As String = _
    "Public Property {0}() As {1}" + Cr + _
    "  Get" + Cr + _
    "    Return {2}" + Cr + _
    "  End Get" + Cr + _
    "  Set(ByVal Value As {1})" + Cr + _
    "    If ({2} = Value) Then Return" + Cr + _
    "    {2} = Value" + Cr + _
    "  End Set" + Cr + _
    "End Property" + Cr

  Public Sub WriteProperty()
    Dim PropertyName As String = _
      InputBox("Property name:", "Property Name")

    Dim PropertyType As String = _
      InputBox("Property type:", "Property Type")

    Dim FieldName As String = _
      InputBox("Field name:", "Field Name")

    Dim Code As String = String.Format(mask, _
      PropertyName, PropertyType, FieldName)


    Dim Selection As TextSelection = DTE.ActiveDocument.Selection

    Selection.Insert( _
      String.Format(mask, PropertyName, PropertyType, FieldName))
  End Sub

The new code is comprised of the last two statements (shown in bold). The first new statement requests the ActiveDocument and the TextSelection from that document. This will be the file and location in which the user will want to insert the code-generated property statement.

At this juncture we can run the completed macro in the Macros IDE (make sure there is an active source code module in VS.NET), to ensure that all of the mechanics are in place and working correctly. Once satisfied that the code generator works correctly we can incorporate the macro for easy access into the VS.NET IDE.

Integrating the Macro Code Generator into the IDE

The macro can be run from the Command window by typing the complete path to the macro in the VS.NET Command window. (The path is Macros.[macros project].[module].[public subroutine]. For our example, the literal path will be Macros.MyMacros.Generator.WriteProperty.) However, the purpose of writing a code generator is to improve productivity and opening the Command window, remembering and typing a long path requires quite a bit of effort. We can do better.

An additional improvement would be to incorporate a button, menu, or hotkey into VS.NET, associating the shortcut with the macro. The remaining steps demonstrate how to create a new toolbar, add a button to that toolbar, and associate our new macro with the toolbutton.

Adding a Toolbar

To add a toolbar to VS.NET select Tools|Customize. Navigate to the Toolbars tab (see figure 2). Click the new button and type the name of the new toolbar. I used the name Code for my toolbar.

Figure 2: The Customize dialog showing the Code toolbar after being added with the New button.

The Code toolbar will be floating after you create it. You can drag and drop the new floating Code toolbar onto the main toolbar, if you prefer.

Adding a Toolbar Button

With the Customize dialog open we want to add a button to the Toolbar. The button will invoke our macro. To add the button, click the Commands tab, select Macros from the Categories list and drag the WriteProperty macro from the Commands list (figure 3) to the Code toolbar.

Figure 3: Select the Macros category and drag the macro to the toolbar to create a toolbar button for the macro.

By default the toolbar button will have the same name as the command. Again, with the Customize dialog open we can right-click on the toolbar button to further modify values. One such useful modification is to shorten the toolbar button text. I modified the toolbar button for the macro to just 'Property' (see figure 4). You also have the option of adding an icon and concealing the button text from the toolbar buttons context menu.

Figure 4: With the Customize dialog open we can customize toolbar buttons with the associated context menu—as shown in the figure.

Assigning a Hotkey to the Button

Generally I find shortcuts a helpful aid to productivity. We can further simplify the process of invoking the macro by associating an available shortcut with the macro. Using the same Commands tab of the Customize dialog click the Keyboard button (see figure 3). Find the WriteProperty macro (see figure 5) and place the cursor in the Press shortcut key(s) edit field. Press the key combination you'd like to assign to the macro. If you use an existing combination then you will see—in the Shortcut currently used by edit field—the command assigned to that shortcut. (I used Ctrl + P, Ctrl + P to invoke the WriteProperty macro.) When you've selected a shortcut click the Assign button to associate that shortcut with the macro command. Close the Customize dialog.

Click here for larger image

Figure 5: Modify the keyboard shortcuts in the Options dialog.

There are many ways to extend and customize Visual Studio .NET to make you more productive. Combining macros and keyboard shortcuts is a pretty low-tech strategy that can yield excellent results.

Before we close I'd like to talk about the code generator for a moment. The WriteProperty macro does not account for the precise positioning of the generated code. In its current incarnation pagination has to be handled by the user. With some modifications one could precisely position and format the generated code. Formatting and pagination are left to the reader. In addition, one could shorten the code generator by adopting some simple conventions. For example, if you adopted an F-prefix for fields then you could modify the macro to require only the property and type and output the field name—parameter {2} from listing 4. Further, with a modicum of ingenuity one could write code to read the fields automatically and generate the property statements. A benefit of writing modular macros is that you can grow the code base, layering new functionality over time.


Visual Studio .NET incorporates macros that are written with the Visual Basic .NET language. These macros can tap into the tremendous power of the VS.NET IDE's automation object model to automate any task desired. By writing modular macros and growing a shared code base over time a development team can radically increase their productivity.

Excellent tools promote excellent results. By automating repetitive tasks, like writing code generators, one can accelerate code production, reduce tedium and errors, and promote hyper-productivity.

About the Author

Paul Kimmel is a freelance writer for Developer.com and CodeGuru.com. Look for his upcoming book, Visual Basic .NET Power Coding, from Addison-Wesley. Paul Kimmel is available to help design and build your .NET solutions and can be contacted at pkimmel@softconcepts.com.

# # #

Page 2 of 2

This article was originally published on May 28, 2003

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date