View complex data types with custom visualizers in Visual Studio 2005.
Have you ever been debugging an application
and decided that you need to view the contents of a
DataSet that is being shown in your
Locals or Watch window? Well, if you
tried this before Visual Studio 2005, you would have had quite a hard
time actually getting to the rows and values of the datagridit
is no small task. You would need to go from DataSet
This view is hard to get to, hard to use, and doesn't even include column names.
Visualizers make this process much easier and more enjoyable. Visualizers provide customized views of data while debugging. Instead of the normal limitations of the debug windows, visualizers are custom Windows Forms that can display the data in any way imaginable. If you had a type that represented an image, you could display the actual image using the visualizer, instead of the text you would normally see in the debugger window.
When you are debugging an application, a small magnifying glass will appear next to the variable in the debugging window if a visualizer exists for that type. You can click on the magnifying glass to launch into the custom visualizer for this type. This can be seen in Figure 5-34.
By clicking on the magnifying glass, you can select a visualizer to use for this data type (there is a drop-down because multiple visualizers can be associated with a single type). This drop-down menu allows you to choose which visualizer you want to use.
After choosing the DataSet Visualizer, you will see your DataSet displayed in an easy-to-view form, as shown in Figure 5-35.
As you can see, the visualizer provides an easy-to-understand view of the data contained in the DataSet.
By this point, you may be thinking, "Hey, I have complex types that I use all the time and I wish I could write a visualizer for them." Well, you can. In this section, I am going to cover how to do exactly that by writing a visualizer for a simple class called Car that includes four properties with the following names: CarID, CarMake, CarModel, and EngineType. Because I need to reference the same class from both the visualizer and the application, I am going to put this class in its own project called CarLib.
The first step is to create a new Class Library project in the language of your choice. I am going to call the project CarVisualizer. After creating the project, the next thing you need to do is create a reference to the Microsoft.VisualStudio.DebuggerVisualizers.dll, which can be found on the .NET tab of the Add Reference dialog. This assembly contains all of the interfaces and classes that you will need to create a custom visualizer.
The next step is to create a new class, which I will call CarForm. This class will be the form that displays data about the class. Since this is a class library project, you will need to add references to the System.Windows.Forms and System.Drawing assemblies (Located under the .NET tab in the Add Reference dialog) and then also add a using statement for both namespaces to the top of the class file. Next, you will need to set this class to inherit from Form. Once this is done, you will be able to edit the file just as if it were a form in a Windows Forms Project. When creating your visualizer form, you should create a constructor that takes an instance of your class. This way, when creating the form, you simply need to pass the object from Visual Studio to your form in the constructor.
After designing the visualizer form, you need to create the class that will interface with Visual Studio. The job of this class is to receive the call from Visual Studio and then create a new instance of your form, passing in the value of the object. To do this, you need to add another class to your project, which I will call DebuggerInterface. The first thing you will need to do is add a using statement for the System.Diagnostics namespace; this will give you access to the interface you need to implement. Next, you need to tell your class to implement the IDebugVisualizer interface. Using the smart tag, you can autoimplement this interface explicitly [Hack #8] , and Visual Studio will add the following code for you:
void IDebugVisualizer.Show(IServiceProvider windowService, IVisualizerObjectProvider objectProvider, VisualizerUIType uiType) { throw new NotImplementedException( ); }
Now you need to replace the line throwing a NotImplementedException with actual code: first get your object, and then call your form, passing in the object:
Car carClass = (Car) objectProvider.GetObject( ); new CarForm(carClass).ShowDialog( );
When Visual Studio calls your Show method, you will first get the Car class from the object provider using the GetObject() method, and then you will create and show an instance of your custom form class, passing in the object.
Next, you need to add an attribute to your namespace, but using the assembly: target:
[assembly:DebuggerVisualizer( typeof(VisualizerObjectSource), typeof(CarVisualizer.DebuggerInterface), VisualizerUIType.Modal, Target = typeof(CarLib.Car), Description = "Car Visualizer")] Namspace
This attributes parameters specify the following things:
The first parameter tells Visual Studio what object source to use; in this case the default VisualizerObjectSource should work just fine.
The second parameter tells Visual Studio the type that should be called.
The third parameter tells Visual Studio that your visualizer is of type Modal.
The Target parameter tells Visual Studio the type that your visualizer is written for.
The Description parameter specifies the text that will be shown in the menu during debugging.
For Visual Studio to detect and use the visualizer, you will need to copy it to \Documents and Settings\<username>\Visual Studio\Visualizers, which would make the visualizer available only to you; alternatively, you could copy it to <Visual Studio Install Directory>\Common7\Packages\Debugger\Visualizers, which would make it available to all users of your system.
|
Now you need to throw together a quick little application that uses your Car class and that you can use to test out the visualizer. The test application will need to reference the CarLib assembly that contains the Car class. The test application simply needs to create a car class and populate its fields.
You can now start the sample application and launch the debugger. When you hover over the Car class, you will see the visualizer in the list, as shown in Figure 5-36.
After you select the visualizer, you will see the custom form with the object's data, as shown in Figure 5-37.
Custom visualizers are a great improvement over the limited amount of data you could see in previous versions of Visual Studio. If you have a complex object, it will be well worth the time to write a custom visualizer to make debugging that much easier.