Click here to Skip to main content
15,867,750 members
Articles / Programming Languages / C++
Article

x.doc - a code documentation comment manager add-in for VS2005

Rate me:
Please Sign up or sign in to vote.
4.69/5 (17 votes)
17 May 200720 min read 132.7K   641   77   33
x.doc is a Visual Studio 2005 add-in that provides a means to manage and visualize source-code comment documentation interactively in the IDE

Contents

Introduction

x.doc is short for "External Documentation." It is a Visual Studio (VS) 2005 add-in that provides a means to manage and visualize source-code comment documentation interactively in the IDE. Its main feature is that it provides an easy way to 'externalize' the documentation comments using the documentation XML <include> tag. It also has many other features which are documented in the Features section below. This type of add-in is not new and has been developed by others - see the Resources section below. x.doc, however, is completely developed in C#, uses no third-party libraries and is built specifically for VS2005/.NET 2.0. Currently x.doc only supports documentation management for C# code files, but sufficient place-holders have been coded to make this add-in work for the other languages. Although challenging, it should be a feasible exercise.

Good source-code documentation can be very useful and is considered imperative in many commercial development environments. VS provides a very efficient method for placing documentation directly in the code using special comment delimiter tags and embedding the text in special XML tags. An overview of how this works can be found at [1] (listed in the Resources section below). VS2005 now provides even smarter code-completion for the inputting of documentation, as well as Intellisense prompting of XML tag keywords. This makes it very easy for documentation to be directly 'coded' into the source-code files using XML. However, large blocks of documentation delimited with XML tags are cumbersome and difficult to read directly in the code, and can even make the readability of the code itself difficult. The answer is to replace the entire block of documentation with a single <include> tag that contains a reference to the block of documentation saved in an external file. Of course, once the documentation has been located in a separate documentation file, it offers the opportunity to further manage and utilize the documentation and the source-code as separate entities.

If using <include> tags is not to your taste, the add-in also provides navigation and outlining functionality specifically for traversing blocks of documentation.

Disclaimer

The add-in provides comprehensive functionality and parts of the code maybe considered complex. The objective of this article and its accompanying source-code is to provide a fairly complete example of how to write such an add-in and to demonstrate the way the add-in should interact with the VS IDE. It is not guaranteed to be code-complete, nor is the code guaranteed to be bug-free. Although care was taken in the design and coding of the add-in and industry-accepted standards were used in the development, the code should be regarded as demonstrative only, and not necessarily of the quality considered to be "industrial strength."

Resources

  1. How to: Use the XML Documentation Features (C# Programming Guide) - MSDN reference for using the C# documentation features in your source-code.
  2. XML Comments Let You Build Documentation Directly From Your Visual Studio .NET Source Files - J. Andrew Schafer. Comprehensive information and techniques for rendering the documentation XML to HTML using XSL/T and CSS styles.
  3. NDoc Code Documentation Generator for .NET - NDoc generates class library documentation from .NET assemblies and the XML documentation files generated by the C# compiler. NDoc uses pluggable documenters to generate documentation in several different formats, including the MSDN-style HTML Help format (.chm), the VS .NET Help format (HTML Help 2), and MSDN-online style web pages.
  4. Visual Studio 2005 Automation Samples - These Microsoft code samples show you how to build VSMacros projects, add-ins, and wizards.
  5. Retrieving a CodeElement reliably in VS.NET 2005 - Using the DTE.ActiveDocument.ProjectItem.FileCodeModel object to retrieve the CodeElement in Visual Studio 2005.
  6. SlashDocs: Manage C# XML Documentation in External Files - A Visual Studio Add-In to help to write and maintain C# XML Comment Documentation in external files included using the C# Documentation Comment <include tag. Freeware. Installer application for VS2003/.NET 1.1. Source-code not available.
  7. CR_Documentor - The Documentor Plug-In for DXCore - An elegant documentation visualizer with very similar functionality to this add-in. Requires the Developer Express, Inc. DXCore plugin for Visual Studio. Freeware. Installer application for VS2003/.NET 1.1, also works in VS2005/.NET 2.0. Source-code not available.

Features

The figure below shows the x.doc windows within the VS IDE:

Screenshot - Figure1.gif


Figure 1: The Visual Studio IDE with the x.doc Visualizer and x.doc Output windows shown with a C# source-code window

x.doc provides two windows:

  • The Visualizer window, which is the window that provides the rendered XML documentation text, using a defined set of XSL templates and a CSS. This window is interactively updated as the caret is moved in a code-editor window. If the documentation is not well-formed XML or an error occurs in the rendering, an error is displayed in this window. If the caret is not positioned in a documentation block, the message "No documentation" is displayed. This window is implemented to work as a standard tool window in the IDE and can be floated, docked, etc. like any other tool window.
  • The Output window is similar to the IDE build window in that it displays the error with the appropriate source-code file path, line and character position offsets. Double-clicking the error line in this window will move the caret to the referenced editor window and the offset in the code at which the error has occurred. It shares the standard output window; its content is displayed by selecting the x.doc menu-item in the 'Show output from:' selector.

x.doc provides a menu tool-strip above the Visualizer window. The available commands are described below, as they are ordered on the tool-strip from left to right:

  • Prior Documentation Item: This button command moves the caret to the prior documentation block in the code editor window and selects the block as shown in Figure 1 above.
  • Next Documentation Item: This command moves the caret to the next documentation block.
  • Collapse All Documentation: This command traverses the entire code document and outlines the documentation blocks. Each documentation block is shown only by three ellipses ("...") and is an effective way to quickly hide all the documentation.
  • Import Documentation Item: This button command imports the documentation from an external file and embeds it as a documentation block in the source-code. This will only happen if the caret is positioned over a single-line documentation block containing a well-formed <include> tag that points to a valid external documentation file with a name attribute that can be resolved to a documentation item in the external file. See The code section for constraints on the use of this tag.
  • Export Documentation Item: This command reverses the action of the "Import Documentation Item" above. The documentation block is exported to the external documentation file and a suitably formed <include> tag is substituted in its place. See The code section for constraints on the use of this tag. Note that badly-formed XML is exported as-is, so it is best to check the Output window for errors before exporting the documentation block.
  • Import All Documentation: This command works the same as the "Import Documentation Item" above, except that it traverses the entire source-code file and imports all documentation.
  • Export All Documentation: This command exports all documentation to the external documentation file, reversing the action executed by "Import All Documentation" above.
  • Documentation Display Style Selector: This selection list will accommodate any number of XSL/CSS templates which are imported from external .xsl and .css files when the add-in is first loaded. The XSL/CSS files x.doc.xsl and x.doc.css are included with the x.doc add-in installer, providing a pseudo-MSDN documentation look-and-feel. Obviously, these files can be modified or more style files added. These can then be individually selected, causing the documentation to be immediately re-rendered using the selected style. It is also possible to extend the VS IDE documentation tags and provide customized documentation functionality. NDoc [3] already does this to provide the various standards of documentation-styles, including their MSDN style, which is exactly like the Microsoft H1 and H2 Help.

x.doc is completely NDoc compatible, in that the XML files that are generated by VS when you compile with the /doc:file option can be used as-is with NDoc. This applies whether the documentation is read directly from the source-code or from an external file.

Installation and usage

The installer package is found in the file xdocsetup.zip. It contains the file setup.exe and setup.msi. To install the add-in, run the setup.exe application and follow the install instructions. The add-in files are installed in the [PersonalFolder]\Visual Studio 2005\Addins folder on your computer. This normally equates to something like C:\Documents and Settings\John\My Documents\Visual Studio 2005\Addins if your computer logon name is "John," and you are running Windows XP. the following files are installed in the add-in folder:

  • x.doc.Addin: VS 2005 extensibility add-in XML file
  • x.doc.dll: Add-in assembly
  • x.doc.css: Add-in CSS file for the x.doc render style
  • x.doc.xsl: Add-in XSL file for the x.doc style transformations

Once installation has completed, VS can be started. The x.doc Visualizer window should appear as a floating window. If the x.doc window is not visible, the VS Add-in Manager window can be used to activate the x.doc add-in. This is done from the Tools/Add-in Manager... menu item of VS. In the Add-in Manager dialog, tick the "Available Add-ins" and "Startup" columns for the x.doc add-in. To ensure that these settings are permanent, open the x.doc.Addin file in a text-editor, and check that the following text is present:

XML
..
<Extensibility ..>
  <Addin>
    <LoadBehavior>1</LoadBehavior>
    <CommandPreload>1</CommandPreload>
  </Addin>
</Extensibility>
..

The above settings indicate that the add-in is available and that it is loaded when VS is started. The zip file xdocsource.zip contains the source-code for the add-in and comprises a C# project -- x.doc.csproj, which is the build project for the x.doc add-in -- and Setup.vdproj, which is the x.doc installer project. In order to debug the add-in, read the text-file readme.txt in the x.doc project and follow the listed instructions. The VS solution file x.doc.sln contains these projects and provides the complete build environment for x.doc.

The code

This section highlights important implementation details of the x.doc add-in. The more obvious and simpler code sections are not discussed and should be easy to follow in the source-code files.

Add-in components

The x.doc add-in window is implemented as a VS tool window that can be docked and floated exactly as the built-in tool windows of the IDE. It is defined in a class x.doc.ToolWindowControl, which is derived from System.Windows.Forms.UserControl. The window was implemented using very similar code to the Toolwindow sample in [4]. The window is instanced in the add-in response method Connection.OnConnect, which is called by the VS extensibility interface when the add-in is connected to the VS IDE:

C#
private Window _windowToolWindow;
..
..
// Create the tool window
object programmableObject = null;
string guidstr = "{FCBF911C-17BA-4260-88A5-9BD84C5C1188}";
EnvDTE80.Windows2 windows2 
    = (EnvDTE80.Windows2)_applicationDTE2Object.Windows;
System.Reflection.Assembly asm 
    = System.Reflection.Assembly.GetExecutingAssembly();
_windowToolWindow = windows2.CreateToolWindow2(_addInInstance, asm.Location,
   x.doc.ToolWindowControl.ToolWindowClassName,
   x.doc.ToolWindowControl.ToolWindowName, 
   guidstr, ref programmableObject);
// Set the picture displayed when the window is tab docked
_windowToolWindow.SetTabPicture(Resource.x_doc_tool_bmp.GetHbitmap());
_windowToolWindow.Visible = true;
..

The x.doc ToolWindow consists of a System.Windows.Forms.ToolStrip object that contains the command buttons and style-selector. The x.doc Visualizer is a standard System.Windows.Forms.WebBrowser. The x.doc Output window is implemented by referencing the existing VS output window, manipulated through the standard EnvDTE.OutputWindow interface:

C#
// Create the output window
OutputWindow outputWindow = (OutputWindow)_applicationDTE2Object.Windows.Item(
   Constants.vsWindowKindOutput).Object;
// Add the x.doc output window as a selectable pane.
_outputWindowPane = outputWindow.OutputWindowPanes.Add(
   x.doc.ToolWindowControl.ToolWindowName);

Text editor caret tracking and DTE events

The most important function of the add-in is to track the caret (text cursor) in the VS active text-editor window as the user clicks or types in the window. This is done in order to interactively display the rendered documentation XML in the Visualizer window. The way this works is as follows:

  1. When the caret information has changed -- this is defined as a change in the line, and/or the character position in the line, and/or the active document has changed in the IDE -- a notification handler is called which determines if the active document has changed. If so, the currently active external documentation is saved to the external file, and the appropriate external documentation file is read into memory for the newly activated document.
  2. The text under the caret in the text-editor is analysed. If it is inside a documentation comment then the extents of the documentation, including the leading comment characters, are determined. Information about the documentation block is returned, including the block start and end points, as well as the textual content of the block. If the caret is not positioned on any documentation comments, the content text string is null and the 'NoDocTag' (No Documentation) is displayed in the Visualizer window.
  3. The XML documentation is extracted from the comment-block and rendered using the active XSL/CSS templates. Then the resulting HTML is set in the Visualizer window. If the extracted XML string is not well-formed or if an error exception occurs during the rendering process, a suitable error message is displayed in the Visualizer and Output windows. In most cases, the error message displayed in the Output window provides navigation to the cursor position in the active document where the error occurred.

The code below shows the control method that provides the above functionality:

C#
private void UpdateCaretResponse(bool updateUI, bool ignoreElapsedTime)
{
   // Get the caret information from the DTE.
   TextCaretTracker.CaretInformation caretInfo = _caretTracker.TrackCaret();
   // If the caret has changed:
   if (_lastCaretInfoUsed != caretInfo)
   {
      // Set the 'Changed' state.
      _caretChangeIndicator = CaretChangeState.Changed;
      if (caretInfo.ActiveDocument != _lastCaretInfoUsed.ActiveDocument)
      {
         // If the document has changed, 
         //switch the external documentation set.
         OnCaretDocumentChange(caretInfo);
      }
      // Set the last update ticks.
      _lastCaretInfoTicks = DateTime.Now.Ticks;
   }
   else
   {
      // If the caret info is in the 'Changed' state:
      if (_caretChangeIndicator == CaretChangeState.Changed)
      {
         // Check if the user has paused for 'PauseInterval' msecs.
         if ((DateTime.Now.Ticks - _lastCaretInfoTicks 
             >= PauseInterval * 10000) ||
             (ignoreElapsedTime))
         {
            // User has paused: Analyse and visualize documentation. 
            OnCaretChange(caretInfo);
            // Set state to 'Unchanged'.
            _caretChangeIndicator = CaretChangeState.Unchanged;
            if (updateUI)
            {
               // Update the x.doc window state.
               UpdateWindowState(caretInfo, _lastDocumentation);
            }
            // Set the last update ticks.
            _lastCaretInfoTicks = DateTime.Now.Ticks;
         }
      }
   }
   // Save the current caret info.
   _lastCaretInfoUsed.CopyFrom(caretInfo);
}

The UpdateCaretResponse method is actually a polling loop as it is called from a System.Windows.Forms.Timer object Tick event handler set in the x.doc tool window control. This works very well because the use of a polling loop provides loose coupling between events generated by the DTE extensibility environment -- which mostly re-/-set state-flags in x.doc -- and the subsequent handling of those events by x.doc. Polling also allows two parameters to be used to control the interaction rate with the IDE. The first is the actual timer Interval, which controls the rate at which caret changes or other DTE events are handled. The second is the pause interval, which is the interval of time that the user does nothing. Only if this elapsed time interval exceeds the preset value in x.doc are the actual documentation rendering and/or other time-consuming functions executed. Setting these time-intervals correctly minimizes the potentially detrimental impact that x.doc has on the typematic responsiveness of the text-editor windows. Currently, the value of 100 msec is used for the timer interval, while the pause interval is set at 500 msec. With these settings, x.doc is acceptably interactive and its impact on the text-editor windows is almost non-existent.

Besides using polling to ascertain the caret position, x.doc also handles some events generated by the VS extensibility interface. Again, code from [4] was used from the EventWatcher project in order to do this. The following code illustrates the setting of event handler delegates:

C#
..
// Get the DTE Events object.
EnvDTE.Events events = _applicationDTE2Object.Events;
// Get the WindowEvents object.
_windowsEvents = (EnvDTE.WindowEvents)events.get_WindowEvents(null);
// Set the WindowActivated event delegate.
_windowsEvents.WindowActivated +=
   new _dispWindowEvents_WindowActivatedEventHandler(OnDTEWindowActivated);
// Get the DocumentEvents object.   
_documentEvents = (EnvDTE.DocumentEvents)events.get_DocumentEvents(null);
// Set the DocumentClosing event delegate.
_documentEvents.DocumentClosing +=
   new _dispDocumentEvents_DocumentClosingEventHandler(OnDTEDocumentClosing);
// Set the DocumentSaved event delegate.   
_documentEvents.DocumentSaved +=
   new _dispDocumentEvents_DocumentSavedEventHandler(OnDTEDocumentSaved);
// Get the EnvDTE80.TextDocumentKeyPressEvents object.   
_textDocumentKeyPressEvents =
   ((EnvDTE80.Events2)events).get_TextDocumentKeyPressEvents(null);
// Set the AfterKeyPress event delegate.   
_textDocumentKeyPressEvents.AfterKeyPress +=
   new _dispTextDocumentKeyPressEvents_AfterKeyPressEventHandler(
   OnDTEAfterKeyPress);
..

The OnDTEWindowActivated handler is used to ensure that if another text-editor window is activated in the IDE, an update of the Visualizer window is forced. This allows the displayed documentation to be updated correctly:

C#
private void OnDTEWindowActivated(EnvDTE.Window gotFocus, 
    EnvDTE.Window lostFocus)
{
   // If the any other window gains focus, force a context switch.
   if (gotFocus.Caption != x.doc.ToolWindowControl.ToolWindowName)
   {
      ForceCaretUpdate();
   }
}

The ForceCaretUpdate method sets the state of the _lastCaretInfoUsed member such that any subsequent caret information read from the text-editor is seen as a CaretChangeState.Changed state. This means the next time the polling loop retrieves the caret information, it will force the appropriate update. This is a very useful technique to provide an asynchronous controlled response to events that come through the VS Extensibility interface.

A similar response method is used for the OnDTEDocumentClosing handler, which is called when a document is closed in the IDE. This may be the active document in the x.doc add-in's context. The OnDTEAfterKeyPress handles the condition where the DELETE key is pressed in the text-editor. This results in neither the caret line, caret character position nor active document changing. The only way to pick up this potential change in the documentation text is to handle the key-press directly. The OnDTEDocumentSaved handler explicitly saves the external documentation file when the source-code document is saved.

The Visualizer window

Once the XML content of the active documentation is extracted, it is transformed into HTML:

C#
public string RenderHtml(string xml)
{
   if (xml == null) return null;
   string html = null;
   if (styleIndex != -1)
   {
      // Retrieve the style as selected.
      RenderStyler style = renderStyles[styleIndex];
      const string uriPrefix = "file:///";
      // Wrap the XML with the root member tag:
      //    <x.member> + xml + </x.member>
      xml = SetXmlRootTag(xml, MemberTagName);
      StringReader stringReader = new StringReader(xml);
      StreamReader streamReader = null;
      StringWriter stringWriter = null;
      XmlTextReader xmlReader = null;
      try
      {
         // Create new xpath document.
         XPathDocument xpathDocument = new XPathDocument(stringReader);
         // Create new compiled xsl transform.
         XslCompiledTransform xslTransform = new XslCompiledTransform();
         // Load the transform from the .xsl file.
         streamReader = new StreamReader(style.XslPath);
         xmlReader = new XmlTextReader(streamReader);
         xslTransform.Load(xmlReader);
         // Create a .css file-path parameter to be passed to the transform.
         XsltArgumentList args = new XsltArgumentList();
         args.AddParam("csspath", string.Empty, uriPrefix + style.CssPath);
         // Create a navigator and transform the XML.
         XPathNavigator xpathNavigator = xpathDocument.CreateNavigator();
         // Write the HTML to a string.
         stringWriter = new StringWriter();
         xslTransform.Transform(xpathNavigator, args, stringWriter);
         html = stringWriter.ToString();
      }
      catch (Exception e) {..}
      finally {..}
   }
   else {..}
   return html;
}

The path parameter is passed to the transform, where it is used to generate the link to the .css file as the following excerpt from the .xsl file shows:

XML
..
<xsl:param name="csspath"/>
..
<xsl:template match="x.member">
   <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
         <link rel="stylesheet" type="text/css" href="{$csspath}"/>
      </head>
      ..
   </html>
</xsl:template>      
..

Since a new HTML page is created for each documentation member, the template should match the x.member tag. A <head> is generated that contains the link where the actual value of the csspath parameter is substituted for the {$csspath} token in the template. Once the HTML is created, it is set as the web-browser DocumentText property:

C#
this.wbDoc.DocumentText = html;  
    // wbDoc is of type System.Windows.Forms.WebBrowser

One of the problems with the .xsl is that it generates live links if link-generating documentation tags like <see cref=".../> are used. Currently these links are not resolved correctly and clicking them produces the standard HTTP-404 Not Found response. A great work-around is as follows: set the HTML in the WebBrowser control using only the DocumentText property results in the WebBrowser.Url.AbsolutePath property, renaming the value "blank" which represents the url "about:blank." However, loading an HTML page by clicking on a link attempts to set the Url property of the browser. The following code allows navigation to be cancelled if a link on the page is clicked, as opposed to the DocumentText property being set:

C#
..
this.wbDoc.Navigating +=
   new System.Windows.Forms.
      WebBrowserNavigatingEventHandler(this.wbDoc_Navigating);
..
..
private void wbDoc_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
   // If the Url is not set through the DocumentText property,
   // cancel the navigation. This means that the HTML links are 
   // disabled in the WebBrowser control.
   if(e.Url.AbsolutePath != "blank") e.Cancel = true;
}

The Output window

By by double-clicking the error line, the VS IDE output window can be used to navigate from a reported error in the output window to the text-position in the text-editor document where the error was caused. This is used by the VS Build window. x.doc provides the same feature to report XML errors, XML-to-HTML transformation errors and other errors that are produced as a result of the x.doc add-in causing an exception. The format of such an error text line is as follows:

{full-filepath}(line,position): {message-text}

where full-path is the full file-path of the source-code file,
      line is the source-code file line-number in the text-editor,
      position is the character position offset in the line, and
      message-text is the actual error message.

Example:
      D:\Development\x.doc\Samples\DocumentationSample\
          DocumentationSample.cs(13,31):
      'value' is an unexpected token. The expected token is '>'. 
           Line 13, position 37.

The errors are reported with line and position numbers based on the offset from the start of the XML string extracted from the documentation block. The FormatDocumentationError method converts these values to the correct line and column position, relative to the actual source-code file.

External documentation

A powerful feature of documentation comments is that the documentation can be saved in an external XML text file, and referenced using a single comment line from the source-code file. This feature is built into x.doc and the reference works as follows, shown in a normal comment block for C#:

XML
/// <include file='xdoc\{code-file-name}.xdoc' 
// path='x.doc/x.member[@name="{code-element-name}"]/*'/>

The <include> tag requires two attributes:

  • The file attribute: This attribute provides the path of the external document file. It can be an absolute or relative path. x.doc will generate a separate documentation file for every source-code file. It will have a file path of ".\xdoc\" to the source-code file path, the same file name as the source-code file, and an .xdoc file extension. In this way, the documentation file can be easily moved with the source-code file to another VS project, without loosing any documentation text.
  • The path attribute: This attribute provides the reference to the x.member element in the external documentation XML that is identified with the name attribute that has the same value as contained in {code-element-name}.

An excerpt is shown from a typical external documentation file:

XML
<?xml version="1.0" encoding="utf-8"?>
<x.doc>
..
..
<x.member name="x.doc.CSharp.Samples.DocumentationSample.DocumentationSample">
<summary>
Initializes a new instance of a 
<c>DocumentationSample</c> type.
</summary>
<example>
The following is an example of initializing a 
<c>DocumentationSample</c> type:
<code>
   // Create the type.
   DocumentationSample ds = new DocumentationSample();
   if (null == ds)
      return;
   return ds.SomeMethod("someString");
</code>
</example>
</x.member>
..
..
</x.doc>

The required <include> element in the referencing code will be:

XML
<include file='xdoc\DocumentationSample.xdoc' path='x.doc/x.member[
   @name="x.doc.CSharp.Samples.DocumentationSample.DocumentationSample"]/*'/>

From the element defined above, it can be seen that the file-name of the source-code file is DocumentationSample and that the external documentation file is DocumentationSample.xdoc.

The most interesting part of the automatic <include> element generation that x.doc provides is in the generation of the name attribute. The name has to be unique and should perhaps be interpreted by humans as well. The following scheme is used, which should work correctly even if all the documentation for all classes and namespaces in a VS project -- or even a VS solution -- are merged:

{code-namespace-name}.{
       declared-type-name}[.{[method-name] | 
       [property-name] | [event-name] | [enum-value] | ...}]

This construct is the formal or full-name of the construct being commented. It can obtained from the ProjectItem.FileCodeModel property of the Document in the active text-editor window. [5] provides a detailed description of how to do this. x.doc uses this technique in a method called GetCodeElementName to interactively determine the code element that is being documented. GetCodeElementName provides a comprehensive set of validation rules to ensure that the <include> element is correctly formed when it is substituted for the documentation XML. The method returns an EnvDTE.CodeElement object and the name attribute is set to the CodeElement.FullName. One caveat: if a code-file is edited that is not part of any of the loaded VS projects, the ProjectItem.FileCodeModel property is null. This means that for these files, the documentation can be imported but not exported, as it is impossible to generate the required name from the ProjectItem.FileCodeModel property.

Another interesting problem was encountered when replacing the TextSelection of the active source-code Document. Using the TextSelection.Text or TextSelection.DestructiveInsert members, VS attempts to format the replaced text as if it is being typed in; i.e. XML closing tags are added immediately after the opening tags! The way around this is to copy the text to the clipboard and then paste it into the document:

C#
..
// Do a copy/paste of the replacing code
// to avoid typematic formatting of documentation
// comments, which happens when setting the Text
// property or doing a DestructiveInsert.
Clipboard.SetData(DataFormats.Text, commentSection);
selection.Paste();
..

Update wish-list

If time permitted, the following may have also worked:

  1. Undo support: Exporting and importing of documentation are, in essence, editor-based operations. As such, they can be undone using the VS Edit/Undo ... commands or the Ctrl+Z key. Currently, x.doc only supports undo actions on the source-code file, not the external documentation file. The result is that the two files can get out of synchronization and produce unexpected Documentation not found errors. There are a few ways around this: only the currently active document's external documentation is loaded into memory in a Hashtable. x.doc could be modified to load every loaded source-code document's documentation and switch between the various Hashtables as the active document is changed. Then, instead of saving the documentation every time an active document becomes inactive (when that text-editor window loses focus), it need only be saved when the source-code itself is saved. x.doc adds the documentation block to the external documentation Hashtable when the documentation is exported. When it is imported, the entry in the external documentation Hashtable is deleted. Currently, in the installer add-in, the deletion is not done. Only the documentation is substituted for the <include> element in the source-code.
  2. Add to project: As the external documentation file is integral to the source-code file if <include>s are used, it should be added as a source-code dependent file to the project when it is created.
  3. Add-in settings: Some of the attributes provided are arguably properties that should be under user control. A useful feature would have x.doc support the modification of these properties in the VS Tools/Options... Options Dialog. [4] provides a ToolsOptionsPage sample add-in that does this.
  4. NDoc detail documentation: It should be possible to provide some of the sophistication of NDoc [3] interactively, without the need to reflect the declared types from the compiled assemblies. Using the ProjectItem.FileCodeModel to do this should be investigated.
  5. Support for other .NET languages: An add-in such as this should at least provide the same support for VB and C++ as well as the currently supported C# language. Place-holders (read TODO:) have been placed in the code which should make this possible. This feature may form the basis for the next update of this add-in.

Release history

17 May 2007: Version 1.0.1

  • Article edited and posted to the main CodeProject.com article base.

17 May 2006: Version 1.0.1

  • Created and published.

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.

A list of licenses authors might use can be found here


Written By
Web Developer
South Africa South Africa
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: Installer fails for networkshares Pin
Metaphor12-Oct-06 23:15
Metaphor12-Oct-06 23:15 
GeneralRe: Installer fails for networkshares Pin
Willem Fourie13-Oct-06 0:17
Willem Fourie13-Oct-06 0:17 
GeneralWindow is lost after IDE restart and x.doc makes annoying noises Pin
Kabelsalat21-Aug-06 7:45
Kabelsalat21-Aug-06 7:45 
GeneralRe: Window is lost after IDE restart and x.doc makes annoying noises Pin
Willem Fourie13-Oct-06 0:15
Willem Fourie13-Oct-06 0:15 
GeneralNot listed in Add-in Manager Pin
karnsj@diebold8-Aug-06 9:15
karnsj@diebold8-Aug-06 9:15 
AnswerRe: Not listed in Add-in Manager Pin
Willem Fourie10-Aug-06 1:33
Willem Fourie10-Aug-06 1:33 
GeneralRe: Not listed in Add-in Manager Pin
karnsj@diebold10-Aug-06 6:05
karnsj@diebold10-Aug-06 6:05 
GeneralRe: Not listed in Add-in Manager Pin
Willem Fourie13-Aug-06 21:56
Willem Fourie13-Aug-06 21:56 
GeneralNice Article! Pin
Mattman20612-Jun-06 17:42
Mattman20612-Jun-06 17:42 
GeneralRe: Nice Article! Pin
Mattman20612-Jun-06 18:40
Mattman20612-Jun-06 18:40 
GeneralRe: Nice Article! Pin
Mattman20612-Jun-06 18:49
Mattman20612-Jun-06 18:49 
GeneralRe: Nice Article! Pin
Willem Fourie12-Jun-06 20:21
Willem Fourie12-Jun-06 20:21 
QuestionUsing NDoc's CSS files? Pin
Tony Selke25-May-06 23:15
Tony Selke25-May-06 23:15 
AnswerRe: Using NDoc's CSS files? Pin
Willem Fourie26-May-06 3:58
Willem Fourie26-May-06 3:58 
GeneralExcellent, Thanks !! Pin
Marcos Meli18-May-06 4:46
Marcos Meli18-May-06 4:46 
GeneralRe: Excellent, Thanks !! Pin
Willem Fourie18-May-06 20:31
Willem Fourie18-May-06 20:31 
GeneralRe: Excellent, Thanks !! Pin
Maruis Marais25-May-06 18:06
Maruis Marais25-May-06 18:06 
GeneralRe: Excellent, Thanks !! Pin
Willem Fourie25-May-06 22:05
Willem Fourie25-May-06 22:05 
GeneralWindow does not appear Pin
ThePaleOne17-May-06 6:26
ThePaleOne17-May-06 6:26 
GeneralRe: Window does not appear Pin
Willem Fourie17-May-06 7:07
Willem Fourie17-May-06 7:07 
GeneralRe: Window does not appear Pin
ThePaleOne17-May-06 7:30
ThePaleOne17-May-06 7:30 
GeneralRe: Window does not appear Pin
Fernando A. Gomez F.17-May-06 17:10
Fernando A. Gomez F.17-May-06 17:10 
GeneralRe: Window does not appear Pin
BulaSerg2-Oct-07 4:56
BulaSerg2-Oct-07 4:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.