I really like WPF for showing directly in the Visual Studio Output folder all binding errors, but one annoying stuff is that the output windows is usually crowded with all sort of stuff, so you have an hard life identifying the binding errors from all the other output contained in there. Since Visual Studio 2010 use WPF to render the output windows and use MEF for extension, modifying the aspect of the content of VS2010 is really simple. So I’ve created in few minutes a simple addin to hilite the databinding error in output windows, the example is based on the Diff Classifier SDK sample, that explains how to use the text classification feature of VS2010
First of all create a new Visual Studio Package project
Figure 1: Creating a Visual Studio Package
Now you should add a couple of classes to the project that actually does the coloring for you.
Figure 2: The CustomClassifierProvider will provide the entry point for modifying aspect of output window
The OutputClassifierProvider implements the IClassifierProvider interface, used to create a classifier for a text buffer; basically its purpose is creating a classifier capable to format text, and the ContentType attribute specifies that it formats text for “output” window. Since VS 2010 uses MEF behind the scene to implements part of the plugin extension point, you should simply add the Export attribute telling MEF that this class exports the IClassifierProvider interface.
Then you need to go to the source.extension.vsixmanifest file and add the project as content for MEF exporting like shown in Figure 3.
Figure 3: Remember to add the whole assembly as MEF Component
To have this, simply press the “Add content” button and you can specify everything in the windows shown in Figure 4:
Figure 4: Adding the project as MEF Component.
Now you only need to write the class that actually does the formatting, I called this “OutputClassifierProvider” and it is very simple. It simply implements the IClassifier interface, thus it can give classification to text in Visual Studio, here is the first part of the class.
1: using System;
2: using System.Collections.Generic;
3: using Microsoft.VisualStudio.Text;
4: using Microsoft.VisualStudio.Text.Classification;
5: using System.ComponentModel.Composition;
6: using Microsoft.VisualStudio.Utilities;
7: using System.Windows.Media;
9: public class OutputClassifier: IClassifier
11: IClassificationTypeRegistryService _classificationTypeRegistry;
13: internal OutputClassifier(IClassificationTypeRegistryService registry)
15: this._classificationTypeRegistry = registry;
18: #region Public Events
20: public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;
The real work is done into the GetClassificationSpans method.
1: public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
3: ITextSnapshot snapshot = span.Snapshot;
5: List<ClassificationSpan> spans = new List<ClassificationSpan>();
7: if (snapshot.Length == 0)
8: return spans;
10: var text = span.GetText();
12: if (text.StartsWith("System.Windows.Data Error", StringComparison.OrdinalIgnoreCase))
14: IClassificationType type = _classificationTypeRegistry.GetClassificationType("output.wpfbindingalert");
15: spans.Add(new ClassificationSpan(span, type));
16: } else if (text.IndexOf("error", StringComparison.OrdinalIgnoreCase) >= 0)
18: IClassificationType type = _classificationTypeRegistry.GetClassificationType("output.alert");
19: spans.Add(new ClassificationSpan(span, type));
22: return spans;
Basically I simply check if the text inside the span starts with “system.windows.data error” and if true I add the classification output.wpfbindingalert, and if contains the text error somewhere I add the classification output.alert, but what is a classification? If you go further down the class code you can find the definition of those two classification
3: internal static ClassificationTypeDefinition outputAlertDefinition = null;
8: [ClassificationType(ClassificationTypeNames = "output.info")]
10: internal sealed class OutputInfoFormat : ClassificationFormatDefinition
12: public OutputInfoFormat()
14: this.ForegroundColor = Colors.Green;
15: this.IsBold = true;
As you can see it is based on a simple static ClassificationTypeDefinition property then a class that inherit from ClassificationFormatDefinition and the game is done. Now you can press F5, start Visual Studio in Experimental Hive, open a wpf project with binding errors, run and look at you new colored output folder.
Figure 5: Binding errors are now hilited in the output folder.
It is amazing how simple is to extend VS 2010 thanks to MEF.
Code is downloadable here.