Sunday, Jan 6, 2002, 12:00 AM in .NET
VS.NET Fun Facts
After about a month of banging my head on it, Visual Studio.NET has become my favorite IDE of all time. To save you the bruising, I thought I'd post some productivity tricks and traps I've learned [1] that make VS.NET useful. If you've got your own, send them to me and I'll post the good ones.
DISCLAIMER: I always leave the standard VS.NET key bindings, i.e. I don't set it to VC6 style. In general, I just learn the default keystrokes for things instead of changing them. Saves me time when repaving my machines or sitting down at strange machines. If you've changed key bindings in your VS.NET, these keystrokes aren't likely to work, but the tricks will still be useful if you can figure out what the key bindings are.
Download
If you don't already have VS.NET, run, don't walk, to MSDN to download a 60-day evaluation of VS.NET Professional.
Tricks
- The most important thing I've done to make VS.NET useful for me is
to unpin all of the windows. This gives me tons of room for the source
or design view. This, combined with the keystrokes to pull out
the windows (below) as I need them, is probably my favorite feature of VS.NET.
- The 2nd most important thing to know is that VS.NET can be invoked
from Start->Run using its name "devenv" (no quotes). Therefore,
to
start VS.NET, type Ctrl-Esc, R, devenv, Enter. Much better than
digging into the deep Programs menu.
- Make sure to move the "Visual Studio .NET Command Prompt" that's
buried deep inside of Start->Programs->Microsoft Visual Studio
.NET->Visual Studio .NET Tools to somewhere more handy, e.g. the Quick
Launch toolbar, so that you can get to it easily. You'll be using the
command shell often in your .NET development.
- Let the IDE implement the stubs of an interface function in a
class (not a struct):
- Type the name of the interface after the name of the class, e.g. "class Foo : IDisposable".
- In the Class View (Ctrl-Shift-C), navigate to the class, e.g. Foo, and choose the interface you'd like stubs for under Bases and Interfaces for that class.
- In the context menu (Shift-F10), choose Add->Implement Interface.
- Bask in the glory of
Don Box (who
showed me this trick).
- Let the IDE implement the stub of an virtual function override:
- In the Class View (Ctrl-Shift-C), navigate to the class, e.g. Foo, and choose the method on the base class you'd like to override under Bases and Interfaces for that class.
- In the context menu (Shift-F10), choose Add->Override.
- Bask in the glory of me, who found this all by myself. I found
this digging through the .VSZ files on my system. It looks like you
can add your own context items to the menus, which sounds like
fun...
- If you'd like some samples of VS.NET Add-Ins,
MS provides some. MSDN Magazine provides
an add-in article that you may find useful.
- Likewise, Leo A.
Notenboom has written
a thorough article about how to write an add-in to VS.NET.
- Also, in
A Designable
PropertyTree for VS.NET: Russell
Morris
has built an implementation of the PropertyTree control that you see in
VS.NET's Project Properties dialog. What makes this really cool is that
Russell's control is a great example of what to do to integrate with the VS.NET
Forms Designer.
- If you'd like to add to the Solution, Project, Project Item or
Context Menu wizards for VC++, VC# or VB.NET, you can. Here's
an example of a project item wizard that produces a custom aspx file
and a custom code behind file to go with it.
- While ildasm.exe is very thorough, if you'd like to have a
prettier view of the types in an assembly, you can load it into the
VS.NET Object Browser. Using the file open dialog, click the
drop-down and choose Open With and select the Object Browser. Once
it's loaded, you can unload it by choosing the Remove item from the
context menu of the assembly in the Object Browser.
- This isn't a tip so much as an observation. If you use an #if with
a compilation symbol, e.g. DEBUG or TRACE, notice that as you move
from configuration to configuration that the editor will gray out the
code path that won't be taken. Is that cool, or what?!?
- Read the online documentation. It's *so* much more useful than the
online documentation of old.
- Brock Allen showed me the
3rd tab (Projects) in the Add References dialog for adding references
from one project to the target of another. This works *so* much better
than hard-coding .NET references to a specific output folder.
- Ed Stegman pointed out
that the Toolbox can be used to store snippets of code. Simply select
some and drag-n-drop it on the Toolbox. To paste, drag-n-drop from the
Toolbox to your editor. Of course, this is great for duplicating bugs
as well. : )
- Ed really likes regions, marked using #region/#endregion compiler
directives, too. Now that's he's clued me into the keystrokes (below)
for expanding and collapsing them, I really like them, too. : )
- Ed also reminded me of the Task List and how anything marked with TODO, HACK or UNDONE will be included in your list of tasks.
Andrew Stopford reminded
me that you can set up your own keywords via Tools -> Options ->
Environment.
- If, on the other hand, you hate the Task List,
Kevin Perry suggested the
followings steps to turn if off after a build:
- Go to Tools -> Options -> Environment -> Project and Solutions.
- Uncheck the "Show task list window if build finishes with errors" option.
- Make sure the "Show output window when build starts" option is checked.
- Now go and close the task list window and it's gone for good!
- Several folks have sent along macros that are life savers to them.
If you'd like to do that, I'm happy to post them here along with
your name and a brief description. Please send attached files instead
of inline text, however. Thanks!
- Richard Broida sent along a macro that inserts curly braces and moves insertion point to first line inside, following K&R or MS style, depending on indentation option.
- Joshua Cauble sent along a macro to sort declarations in a VB.NET class to get the items in the wizard bar sorted.
- Don Box sent along a macro to achieve emacs-like M-x compile functionality.
- Peter Andersen sent in
a macro that creates a C# string from an
arbitrary mark, e.g.. if you select the following lines:
<xml>
<hithere>mom</hithere>
</xml>
running the macro produces the following output in the editor:
"<xml>" +
"<hithere>mom</hithere>"+
"</xml>";
-
Drew Marsh pointed out that Ctrl-S works in any of the output windows, e.g. build, debug, etc, to save the contents to a file.
-
It's cool to have MS folk reading this list. Kevin Perry sent me to procedure to bypass the "Attach to Process" dialog that asks what kind of debugger you'd like to pick, i.e. CLR, T-SQL, Native and/or Script, when you click on the Attach... button in the Debug Processes dialog. Ctrl-clicking on Attach... will give you the Native debugger without asking.
-
My good friend Tim Ewald reminded me that one of the coolest features of VS.NET is that the solution explorer is really just a view of your actual project folders in the shell. This is especially useful if you choose Show All Files, so that you can add files to your project that are already in your project directory simply by using the context menu. If you'd like to add a file that isn't in your project, you can do so by opening the file and choosing "Move <file> into Project" from the context menu. This is a poorly named item, however, as it actually links to the existing file outside the project instead of moving it in the file system (although the linking is the correct behavior).
-
To speed the IDE start-up time, you want to avoid the browser being loaded. To do that, from the Start Page, choose My Profile and set At Startup to Show empty environment. Also, close the Dynamic Help window and the Start Page. Now IE will only be loaded on demand.
-
If you like the tabs showing the various files you have open, but miss the ability to show multiple files at the same time, right-click on one of the tabs and choose New Horizontal/Vertical Tab Group. Both tab groups will show simultaneously and you can move tabs (and therefore the window that the tab represents) between tab groups by right-clicking on the tab.
-
Maria Abreu points out that VS.NET, by default, neglects to colorize strings (an omission, IMO). You can colorize them via Tools->Options->Fonts and Colors and it really helps. Thanks, Maria.
-
Graeme Foster posted this tip on the DOTNET mailing list for getting VS.NET to copy the application .config file during the build: simply name the file app.config and put it in the main project directory. At build time, VS.NET will copy the file into the output directory with the build output.
-
Dominick Baier reminded me that by typing "///" (no quotes) above the declaration of a method or property, the C# editor will give you the template for the C# XML documentation tags with all parameters and return value. The IDE will compose these comments into (fairly ugly) HTML-based documentation for your classes using the Tools->Build Comment Web Pages menu item. A much nicer set of documentation from these comments can be generated by NDoc.
-
Kunal Cheda pointed out that if you've got multiple things you'd like to start when running or debugging a solution, you can do so at Solution Explorer->Solution Properties->Startup Project->Multiple Startup Projects. *Very* handy for client-server testing.
-
Nick Hodapp passed along this tip on how to exclude included files that don't change from VC++ dependency checking:
-
Add header file directory names (using full, absolute paths) one per line, to SYSINCL.dat.
-
Exit the development environment.
-
Restart the development environment.
-
Click Rebuild for changes to take effect, noticing a reduction in build times.
-
-
Shawn Van Ness thinks that the clipboard ring "is so cool, it should be back-propped into all of Windows": Using Ctrl+Shift+V as an alternative to the usual Ctrl+V paste command, will "cycle" through the last dozen or so bits of text you've copied onto the clipboard. This simple user scenario demonstrates:
-
Copy "#if DEBUG" onto the clipboard.
-
A few lines below, copy "#else" onto the clipboard.
-
A few lines further below, copy "#endif" onto the clipboard.
-
Scroll down many hundreds of lines... or open a different file, etc.
-
Ctrl+Shift+V to paste "#endif".
-
Ctrl+Shift+V, Ctrl+Shift+V to paste "#else".
-
Ctrl+Shift+V, Ctrl+Shift+V, Ctrl+Shift+V to paste "#if DEBUG".
-
-
Scott Hanselman pointed out that you can set the font size to VS.NET from the command line using the /fs argument, e.g. "devenv.exe /fs 14". This is great for presenters!
-
For the complete list of key bindings, MS provides a Keybindings Table Add-In. Here it is already compiled. Just drop it anywhere, register it as a COM server and the next time you start VS, you'll have a KeyMap command in the Help menu.
-
Russell Sinclair has provided his favorite key bindings in an Excel spreadsheet that prints and folds nicely for keeping it handy.
- Here are my favorite key bindings:
Keys Binding F8/Shift-F8 Navigate compilation errors Ctrl-D Move to mini-buffer Ctrl-Shift-G in mini-buffer or
Ctrl-O in mini-bufferOpen file name in mini-buffer (Ctrl-O seems to open stuff Ctrl-Shift-G does not) "> command" in mini-buffer Execute command Ctrl+/ Move to mini-buffer, typing the leading > for you Ctrl-Alt-A Open the command window Ctrl-PageUp in HTML Design View Open source view Ctrl-PageDown in HTML Source View Open design view F7 in Form Design View Open source view Shift-F7 in Form Source View Open design view Ctrl-Alt-L Solution Explorer F4 or Alt-Enter Properties of selected item Ctrl-Shift-B Build F5 Debug Ctrl-F5 Run, but not debug Ctrl-Alt-J Object Browser Ctrl-Shift-C Class View Ctrl-Space when typing a symbol Complete the symbol you're currently typing or give you a choice of possibilities Ctrl-Space when entering arguments Show the function prototype "-" (no quotes) as the name of a menu item Menu item becomes a separator Ctrl-K Ctrl-F Reformat selection } Reformat scope being closed Ctrl-K Ctrl-C Comment out selected lines Ctrl-K Ctrl-U Uncomment selected lines Ctrl-} Match braces, brackets or compiler directives Shift-Ctrl-} Select match between braces, brackets or compiler directives Ctrl-L or Shift-Del or
Ctrl-X w/ no selectionDelete entire line Ctrl-Del Delete next "word" Alt-F6 Next visible pane (not for use with all windows unpinned) Ctrl-Shift-F12 Jumps to next *whatever*, depending on what's active, e.g. next find result, next task, next error, etc. Ctrl-"-"/Ctrl-Shift-"-" (no quotes) Jumps to last/next place you worked Ctrl-C in the Class View Copies fully qualified name to the Clipboard Ctrl-M Ctrl-M Collapse or expand a region or outlined block (as marked by the [+] and [-] on the left hand side of the editor). Ctrl-M Ctrl-O Collapse everything in the current file Ctrl-M Ctrl-L Expand everything in the current file F12 Jump to the current symbol's declaration Ctrl-G, line #, Enter or
Ctrl-D, line #, Ctrl-GJump to line Ctrl-I/Ctrl-Shift-I + string Incremental search for string Ctrl-R+Ctrl-R Turn on/off word wrap Ctrl+Up/Down Arrow Scroll window up/down without moving the cursor away from the current line Shift+Alt+Arrows
(Alt+Mouse works, too)Column selection (include of line selection)
Traps
- VS.NET's Copy Project uses FrontPage Extensions to publish a web
site from a local testing machine to the deployment machine. This is
virtually important if you don't want to hack on your live web sites. However,
Copy Project sends everything every time instead of sending the deltas, so it's
pretty worthless as far as I can tell. Instead,
Brad Wilson clued
me into the FrontPage Publish Web command, which only publishes
deltas.
- The command window (or > in the mini-buffer) seems really cool,
but I don't know any good commands to type.
Do you?
- Joe Bauer points out that you can, of course, use the command window to print fields or call methods using the ?, e.g. "> ? objMyClass.GetCount()".
- Richard Birkby pointed out the "shell" command, which seems a bit unwieldy for me, but you may like it. ">shell /?" in the mini-buffer will show usage (now that's cool!).
- Drew Marsh points out that the command window (or the mini-buffer with a > prefix) allows you to execute any command provided by the shell, add-ins, or macros. Anything you don't bind to a key combination or toolbar button, you can go into the command window to execute. Also, it supports auto-completion for those of us with poor memories.
- Richard Broida pointed out the use of the "?" command to print variables at debug time.
- John Lam showed me where the docs are for the pre-defined command aliases. He also points out that you can create your own aliases, but you need cool commands first before you can do that. : )
-
Ramakrishna Vavilala recommends a cool alias ">alias ! shell /command cmd /c" which reduces the syntax of the shell command considerably and sends the command output to the Command window.
-
Don Box pointed me at two commands that forces me to learn the keyboard shortcut to put focus in the command window (Ctrl-Alt-A):
-
">open <partial path>" will give Intellisense on the file system, e.g. ">open c:\".
-
">File.NewFile <file name>" will open a new file with the appropriate name and syntax highlighting, e.g. ">open foo.cs". This is even handier when you alias "new" to File.NewFile, e.g. ">alias new File.NewFile", because you can just do this ">new foo.cs".
-
- As far as I can tell, there is no way in a C# project to run
custom pre or post-build commands, either on a project or a file
level. If the VC++ wizards still had a Utility project, that could be
used, but the closest I've seen in VS.NET is a Makefile project.
Anyone have ideas on this one?
- Several folks have recommended a VS.NET Add-In Sample that is supposed to provide this capability.
- Kevin Perry showed me
where the UI scrambler put the Utility project in this version of the
IDE:
- Run the makefile appwizard to create a makefile project.
- Bring up the project properties for the project and look at the general page
- Select “Utility” in the “Configuration Type” property drop down.
- Click Apply.
POOF! Instant Utility project.
BTW: C++ Static Library projects can also double as utility projects in a pinch.
- As cute as the Add Reference menu item is on a project's context
menu, your going to have to avoid Add Reference for COM servers and build the
references by hand if you sign your assemblies (which you should
always do). Apparently a signed assembly is not allowed to reference
an assembly that's not signed and the Add Reference menu item doesn't
sign the generated assembly. All Add Reference does is the moral
equivalent of the tlbimp command line tool anyway, so get used to
calling it yourself using the /keyfile command line argument. If you
import COM Controls, e.g. the WebBrowser control, you'll
need to use aximp instead of tlbimp, but the /keyfile argument is the
same.
However, Jerry Dennany points out that you can have VS.NET itself sign your interop assemblies by going to the Project Properties, and under Common Properties / General there will be a section for "wrapper Assembly for ActiveX / COM Objects." You may place your path to the Key File here, and everything still works from the IDE.
- There are no wizards for standard SDI, MDI or Explorer-style
applications in WinForms as there were in VC++ for MFC applications.
However, the wizard stuff is there, although it's obscure, so maybe I'll build one.
I've certainly done my share of that kind of
work...
- Likewise, there is no built in support for MFC-style document
handling, separation of data and view, command line processing or
command UI handling. I've done my share of
that kind of work, too, and I *will* be building that stuff.
Anyone want to
volunteer to help?
- I don't seem to be able to get a custom control on the toolbox
unless it's part of a separate assembly. What if I have a custom
control in my application? Can I make it show up on the toolbox
somehow?
- Bob Beauchemin pointed out
that I can customize the toolbox and point it at a built version of my
EXE, which sounds kind of awkward, but works.
- Bob Beauchemin pointed out
that I can customize the toolbox and point it at a built version of my
EXE, which sounds kind of awkward, but works.
- I can't tell. Is everything being recompiled every time I build,
regardless of whether the source has changed or not?
- Drew Marsh pointed out that the Incremental Build option in a C#
project will decide whether you rebuild only if it is changed or not.
- Drew Marsh pointed out that the Incremental Build option in a C#
project will decide whether you rebuild only if it is changed or not.
- If a file is "thought of" internally by the IDE as one text, e.g.
Text, and you try to save it as another type, e.g. XML, if you're not
very careful the save
dialog will append the extension of the type it thinks it is, e.g.
.txt. To enforce the extension you want, put double quotes around the file
name, e.g. "foo.xml".
- Neither BeginInvoke nor EndInvoke is shown when calling methods on
a delegate in C#, even though they do in VB.NET. This just seems
wrong...
- Docs on the built-in VsWizardEngine that VS.NET provides would be
nice.
- Jon Flanders says that
they're documented as part of Enterprise Templates.
- Jon Flanders says that
they're documented as part of Enterprise Templates.
- By default, adding a new project to an existing solution wants to
put the new project in a peer directory instead of in a sub-directory.
This seems strange if you're trying to keep these things together
(which, presumably, you are if you're grouping multiple projects into
a single solution). Certainly, I've seen users dig through several
peer directories looking for the solution file. I put sub-projects
into sub-directories by hand, but it would be nice if the IDE did this
automatically.
- Cleaning a project of it's output files doesn't actually work for
C# or VB.NET projects (although the UI shows it as an option, as does
the command line). Tomas Restrepo
has provided
an add-in that provides the missing Clean functionality, along
with a rant on what problems he had building the add-in.
- In spite of CodeWright and every other 3rd party editor supporting
it for years, VS still doesn't support keyword expansion, e.g.
expanding "if( " into "if( | )\n{\n}", so I use
Dexter, from
NilgiriHouse. I don't have to change my typing habits at all, but
I get tons o' text for free.
- The macro recorder is pretty stunted. For example, if I want a macro to switch between some editor settings, e.g. my normal code formatting style and my prose code formatting style, and I record a macro to watch me change the settings, all the recorded macro does is record that the dialog was shown, not what settings I changed. What a let down...
[1] I've learned a ton of these tricks and traps from my fellow DevelopMentor instructors, my students and the .NET mailing list, all of which I can heartily recommend.