Introduction

When I logged on to CodeProject this morning, the weekly poll asked the question, "How wide is your source code?". This led to a discussion in the forums, where Vikram posted a link to this article by Sara Ford:

The article details a little hack that you can make to the registry so that one or more "guidelines" can be dispalyed in Visual Studio. (See the image above for an example of what this looks like in the editor.) So the bottom line is, the end result of this article isn't really due to my own bright idea - the only original part of this is in creating a tool to perform the registry hack for you, with minimal effort on your part.

I won't bother to rehash the content of the article here, as you can read it freely from Sara's blog. I will simply address the tool, and what went into it.

The Tool

The tool is so simple it's almost silly to review it. It took me about 10 minutes to hack together from start to finish. (Update: with all the updates listed below, I'd say there is roughly five hours of work in this now.) Basically, it allows you to select a color to set the guidelines to, and to enter a list of column addresses to place the guidelines at. Click "Apply" and the changes are made. Click "Remove" and the changes are removed. It's a no brainer.

The IsNumeric Problem

C# is a wonderful language, but every now and then, you wander into a situation that leaves you scratching your head in disbelief. One of the things I wanted to do was to make sure that the list of guideline locations was a comma seperated list of integers. My first thought (being an old VB programmer at heart) was to simply Split() the string and check to see if each value was a number by asking "IsNumeric()"? But lo and behold, C# has no such function! The Char type has a similar function, but not String.

My first attempt (and you might have downloaded this copy, see the update below) was to Split() the string, and then "borrow" the function by stealing from VB, like this:

That worked just fine for the most part, then I realized that you could still enter a value such a -9, or 9.5, and it would pass muster. While those values probably wouldn't hurt anything, they weren't helping it any either, so I came up with a new plan, and the one I should have gone with in the first place, using a regular expression to validate the input. Not only did this minimize a lot of code in my program, but it works better in the end.

Update (Aug 14, 2006)

This article and code has been updated since the initial release. The following features and changes have been implemented:

Error checking is now included

The preview textbox is readonly

The preview textbox now correctly updates when you change the guideline locations

The registry is now explicitly closed after each transaction, as reccomended in the comments below

A help file is included

Settings are persisted between sessions

Error checking is now via Regex, much less coding and no VB reference required

Program now reads in value from registry as requested in comments below

More comments added to the source code

Now handles VS 2003 & VS 2005

Help greatly expanded

UI changed to reflect new features

Error handling now uses the ErrorProvider model and is handled more appropriately

Some minor spelling errors corrected

Reduced the size of the source file

Added tab stops

Max. # of guidelines is now enforced

Bugfix: Preview color now displays correctly when loading from registry

Bugfixes: load()

Bugfixes: several required null checks

Known Problems

The code is pretty solid now. The only known "bug" is that I don't currently check for maximum column values - you could enter 20,000 as a column, and unless you have a monitor that wraps around the entire room, you'd never see it. This being a developer tool, I felt it was uneccessary to spell this out.

Special Thanks

To all the people who made suggestions for this tool, especially to Gordon Brandly who suggested some of the UI updates and provided the code to make this work with VS2003. Also, thanks to those of you who put in a 5 vote for this article, I really appreciate it.

Disclaimer

This tool is free and open source, so do what you want with it. Giving me some credit somewhere, for it would be nice, but not required. It does make changes to your registry, so backup your registry before using it! I take no resonsibility for any damage caused to your system by this tool.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

Todd Davis has been working in web and application development for several years, using Silverlight, ASP.NET, VB.NET, C#, C++ and Javascript, as well as a great deal of work with SQL server and IIS.

He currently works for Virtual Radiologic in Eden Prairie, MN, however he is better known for his varied work in the open source community, especially the DotNetNuke project for which he provided several world-renowned training videos and modules. A huge advocate of open source and open knowledge sharing, everything on his website (www.SeaburyDesign.com) is always offered for free.

Whenever he is not actively coding at his laptop (a rarity to be sure), he can be found woodworking, walking with his wife and kids, or motoring along the back roads of MN on his Harley Davidson Fatboy.

Comments and Discussions

I found your article useful and informative, and thank you for the time you took to write it. To appease the corporate security watchdogs, I wrote a completely independent version from scratch, which can be downloaded from http://www.humble-programmer.com/sw_liner.htm[^]. I linked back to this article--and gave you due credit--under the Credits heading.

Thanks for the credit, Todd. I've had two articles for CP half-finished for two years now, but never seem to find the time to finish them. So, this ended up being the first time I've actually contributed any code to CP (even if it was only a small indirect contribution).

One question about the behaviour of your latest version: when I click either of the "Load" buttons, the colour of the picColor control doesn't change, and the text in txtPreview shows the selected colour from colorDialog1 instead of the colour value from the registry (see the last line of the load() function). Is that by design?

Ah, yes - cough, ahem - just did that see if you were watching, yes, that's the ticket. Apparantly you were. Gold star! <sheeping grin>

Good catch Gordon. I'll need to fix that. Maybe I need to sleep more. That is definitely the Bug du Jour. Thanks again for your input thus far. Hope you get around to finishing those articles. I have about a dozen of those "perpetually never finished" projects sitting around.

One final little bug to fix, and it should be done like dinner. Now when I click either Load button, the "Guideline Color" changes, but the sample text and colorDialog1's selected colour aren't updated. The fix, though, is extremely simple. Insert this line:

colorDialog1.Color = picColor.BackColor;

as the second-last line in load(), just before the line that starts with "txtPreview.Text =".

Thanks - actually, upon review I found even more bugs than that. load() was accepting a path parameter but not actually making use of it, and several functions were obtaining a key but not checking for null value, which was causing an error when the key didn't exist.

Me either, as it seems like people want it. After I get this ironed out, I might try and turn this into a VS plugin for convenience sake, although I think most people will tend to run this once and then forget about it afterwards.

Ah, right! I knew there was something I forgot. Blame it on coding while watching reruns of "The 4400", a poor mix to be sure. I will add the feature in the next 24 hours and credit you in the comments Olaf. Thanks for the input.

That is certainly something I can add in. From my understanding, the registry info flushes and closes when the app closes (at the very least. When I was testing it, the changes were made right away). Since we are dealing with only one key, and the app only does one thing (we aren't making hundreds of registry changes) it didn't seem neccessary to specify this explicitly. But to be safe and/or complete, I'll be happy to add it when/if I make changes to the code.

It's still good practice, however, to follow the guidelines of opening system resources as late as possible, and closing them as early as possible, to avoid any issues where the app crashes, leaving unclosed registry keys, allocated GDI objects, etc.

Looks like an interesting concept, though. VS Guidelines. I'll have to try it.