Visual Studio 2005
Visual Studio 2008
ADCollectionsVisualizer is a Visualizer add-in for Visual Studio 2005 and Visual Studio 2008 which allows a wide range of collection and dictionary-style objects to be easily examined.
One of the fantastic new features of the Visual Studio 2005/2008 IDE is the ability to use Visualizers. These are utility windows that attach themselves to various object types within the Visual Studio environment. When you hover the mouse over a variable of one of the supported object types, a magnifying glass icon appears within the popup tooltip, and clicking it opens the Visualizer window for that particular variable, allowing the variable content to be viewed much more easily.
Several Visualizers are included with Visual Studio by default, to allow text to be viewed (as plain text, HTML or XML) and to allow DataTables to be examined more closely. The IDE allows further Visualizers to be written, however, such as ADCollectionsVisualizer.
ADCollectionsVisualizer allows a whole variety of collection and dictionary classes (and objects for all classes that inherit from these classes) to be viewed in a grid, and also copied to the clipboard and saved to disk if required.
Using the Code
The visualizer can be installed by either running the installation executable, or by unzipping the DLL and placing it into your My Documents\Visual Studio 2005\Visualizers or My Documents\Visual Studio 2008\Visualizers directory, as appropriate.
Note that if you are compiling the visualizer from its source code, you can use a Build Event to automatically copy the visualizer to the installation directory. You can find this by double-clicking the My Project icon, then selecting the Compile tab and clicking the Build Events button (such a build event is configured within the provided project file — you will most likely need to change the path to wherever your My Documents directory is located).
After this has been done, simply hover the mouse over a collection object within the IDE whilst in break mode. A small magnifying glass icon should appear; click on this to open the visualizer.
The visualizer supports a wide range of collection-type objects, including:
- All classes derived from
- All classes derived from
- IIS classes, as used by
- VB6-compatible collections
Microsoft.VisualBasic.Collection (values only — keys cannot be retrieved from this type of collection)
The code itself consists of three main classes:
CollectionVisualizer contains the visualizer itself, along with all of the
DebuggerVisualizer assembly attributes. There are quite a lot of these, to handle all of the different types of collection and dictionary classes that the visualizer supports:
Notice that two of the project classes are referenced within every one of the attributes: the first is the
CollectionVisualizer class, which is responsible for doing the work, and the second is the
ObjectSource which packages up all of the data into a form which can be serialized in order for the visualizer to access it. Further details on this are below. The third class reference within each of the attributes points to the type of class for which the visualizer is to function. This changes for each attribute, and the repeated attributes allow all of the supported classes to be handled by the same visualizer class.
If you wish to know more about how to write visualizers, you will find other articles within The Code Project that explain this in great detail.
The latest release now also supports Generic collection objects. These are specified in a slightly different manner within the assembly attributes:
GetType(ObjectSource), Target:=GetType(collections.Generic.List(Of )),
The generic class type is specified using the class name followed by the
Of keyword in parentheses, but with no class type specified. Where multiple class types are required, a comma is used to separate the types but once again no types are specified. This allows the visualizer to work with the generic classes regardless of the types of data that are being stored within them.
The visualizer uses a custom
VisualizerObjectSource in order to package up the data to be visualized. The IDE serializes the data that is to be visualized, and some of the collection types supported by ADCollectionsVisualizer are not able to be serialized. To work around this, the
ObjectSource class extracts all of the data from the collection and puts it into an ADO.NET
DataTable, representing each object's value as a simple
DataTable is then serialized and passed to the visualizer. The
ObjectSource class is responsible for recognising all of the different collection types that are supported and decoding their data into the
DataTable. For the most part this is straightforward, but some of the types (in particular objects that derive from
NameObjectCollectionBase) are a bit more tricky to access than they might have been.
PreviewForm displays the data to be visualized on the screen. It uses a
DataGrid for its presentation, and also offers the ability to copy the collection data to the clipboard or save it to disk in CSV, text or XML formats.
Points of Interest
There are a couple of areas of code that might prove useful or interesting to anyone that hasn't encountered them before — they certainly had me guessing for a while.
The first is the code that accesses the values within an object derived from
NameObjectCollectionBase. I could see that there were two protected members within the class called
BaseGetAllValues — obviously these would be exactly what I need to extract all the data from the collection. However, as they are protected, my code doesn't have any direct access to them.
I used a rather hacky piece of reflection to gain access to these functions. I definitely would not recommend using techniques such as this in production code, but in the context of what the visualizer is trying to do I think they are an acceptable technique. Without them, I would be unable to support collections based upon this class.
The second thing that took some experimentation and research to get right is the customisation of the
DataGrid. By default the grid allows the values to be edited (which is not something that the visualizer supports at present) and highlights the selected cell with a gray background. I created a class named
CustomGridTextBoxColumn which derives from .NET's
DataGridTextBoxColumn and added some code to prevent editing and to properly control the foreground and background colours of the cells. Despite being a bit of a pain to set up, it works very well and provides exactly the functionality I was looking for.
The code that implements the
DataGridTextBoxColumn is as follows:
Public Class CustomGridTextBoxColumn
Protected Overrides Sub Edit(ByVal source As CurrencyManager,
ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle,
ByVal [readOnly] As Boolean, ByVal displayText As String,
ByVal cellIsVisible As Boolean)
Protected Overrides Sub Paint(ByVal g As System.Drawing.Graphics,
ByVal bounds As System.Drawing.Rectangle,
ByVal source As System.Windows.Forms.CurrencyManager,
ByVal rowNum As Integer, ByVal backBrush As System.Drawing.Brush,
ByVal foreBrush As System.Drawing.Brush,
ByVal alignToRight As Boolean)
backBrush = New SolidBrush(SystemColors.Window)
Dim o As Object = Me.GetColumnValueAtRow(source, rowNum)
If o Is DBNull.Value Then
foreBrush = New SolidBrush(SystemColors.GrayText)
foreBrush = New SolidBrush(SystemColors.ControlText)
MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush,
If backBrush IsNot Nothing Then backBrush.Dispose()
If foreBrush IsNot Nothing Then foreBrush.Dispose()
As you can see, two of the class procedures are overridden. The
Edit procedure exits immediately, without calling into the base class. This prevents the edit from taking place. The
Paint procedure does call into the base class (and that's still where the actual drawing of the text takes place), but prior to doing it replaces the foreground and background brushes that would have been used, and substitutes its own to ensure that it has full control over the colours.
If you wish to learn more about changing and extending the behaviour of the
DataGrid, you can find a huge amount of information in the DataGrid section of George Shepherd's Windows Forms FAQ.
Version 1.2 (2008-09-10)
- Added support for
- Visual Studio 2008 support added
Version 1.1 (2007-09-14)
- Added support for collections deriving from
- Released source-code
Version 1.0 (2007-06-03)