Extending Solution Explorer

The following diagram, related to the Solution Extender sample, shows how you can extend the solution view by adding Solution Notes to the Solution node and persisting those notes. The notes can be either shared and persisted in the .sln file, or private and persisted in the .suo file. For more information relating to the .sln and .suo files, see Solution (.Sln) File and Solution User Options (.Suo) File.

This diagram shows the process for saving and viewing notes attached to a solution.

Note

The Solution Extender sample has been implemented to autoload on UICONTEXT_SolutionExists, so it is also a good example of autoloading functionality.

Solution Extender sample
Model Solution Extension

The following steps describe the process for storing and saving notes attached to a solution using Solution Extender that is depicted in the previous diagram.

  1. Solution Explorer points to the CSolution object indicating that it is part of the T:Microsoft.VisualStudio.Shell.Interop.IVsHierarchy.

  2. When the solution is opened in Visual Studio, an entry is made for the solution file (Solution1.sln) in the running document table (RDT). The solution file contains information persisted for the solution which includes Project1 as shown in Solution Explorer. (Information relating to the specific project items and the project itself are contained in Project1's text-based project file. If an element of the project is opened for editing, there is an entry for the project file in the RDT.)

  3. The context menu displayed when the user right-clicks the solution node contains an entry for Solution Notes (not shown in the diagram). From this menu, the user can select either Add New Solution Note or View Solution Notes. Selecting one of these options opens the Solution Notes window. The Solution Notes window contains the following three links:

    • Note Name—The name of the note. The note can be renamed or deleted in the Solution Notes window by right-clicking the name field, or renamed in the Properties window.

    • Issue—This field was added programmatically by the implementation in the sample and can be set to TRUE (to indicate that there are issues in the solution that need to be addressed) or False.

    • Shared—If this field is set to TRUE, the note can be viewed by other users and is stored with the Note Name as a name-value pair in the .sln file. If it is set to false, the note is not shared with other users and the contents of the note are stored with other private user options in the .suo file.

  4. Selecting one of the notes in the Solution Notes window causes the properties for that note to be displayed in the Properties window. The properties shown in the three fields of the Solution Notes window can be changed in the Properties window. In addition to the three fields described above, the Properties window also contains the size of the note consisting of the number of characters in the note.

  5. The class CNoteToolWin implements the Solution Notes window. It is contained within the class CSlnExtPkg that is the class for the Solution Extender Window. When Add New Solution Note or View Solution Notes is selected from the solution menu, a call is made to CSlnExtPkg to open the Solution Notes window.

  6. At the same time, a call is made to CSlnNote. This opens the standard text editor to view the text of the note, or to allow a new note to be written, by calling the CreateDocumentWindow method and passing in the MKDocumentString for the document to be loaded into the window. By specifying the AltDocData flag (CDW_fAltDocData) in this call instead of RDTDocData, you indicate to the environment that you are loading a subset of the RDTDocData document into the text buffer.

    This is important because the entry in the RDT is for the entire solution file. If RDTDocData is called, the .sln file is loaded into the editor rather than the subset of the solution that is the note. This results in an error condition because the same document (in this case the solution file) cannot have two entries in the RDT, indicating that the same document was opened in two different editors.

  7. After a note is created, it is added to the list of notes indicated in the diagram by the three extensions off the CSlnExtPkg box. As indicated by the colors of these side-boxes, two are saved to the sln file and one to the suo file. This is because two of the notes have been set to Shared (Shared = TRUE in the Properties window indicated by Yes in the Solution Notes window) and one has Shared turned off (set to False in the Properties window and indicated by No in the Solution Notes window). Shared notes are saved in the .sln file as text name-value pairs, while unshared, or private, notes are stored in the .suo file and are specific to the user.

  8. When the solution is saved or closed, the users see a dialog asking if they want to save changes made to the solution. Even if the changes are restricted to the solution notes, the changes are registered as part of the solution because the solution had the entry in the RDT. If changes are also made to the project, the project is also listed in the dialog window because when a project file is opened, the project has its own entry in the RDT.

  9. The Solution Notes are persisted with the solution and are loaded and available the next time the solution is opened. Shared notes in the .sln file are available to any user, while unshared notes are only available to the user who created the note when that user's .suo file was loaded with the solution.

  10. There are several solution extension features that the Solution Extender sample demonstrates, and others that you can add by building on the sample. Some of these features include:

    • Adding new tool windows that represent alternate views of the solution.

      This is demonstrated in the sample with the addition of the class CNoteToolWin to implement a new UI and a new tool window, and the use of AltDocData to view and edit a subset of the complete file contained in the RDT. The functionality could be extended by your VSPackage to include abstract views of the solution itself either through an alternative tree view or additional UIs by extracting different subsets of the solution file and displaying them with AltDocData flags in different ways.

      Another example of this functionality is the implementation of the resource editor in Visual C++ and C#. The resource (.rc) file might consist of several different components: string table, dialog template, and accelerator tables. When the file is opened in Visual C++ or C#, the .rc file has an entry in the RDT. When a string table within that file is opened, it is opened with the AltDocData flag to indicate that it is a part (or subset) of the full file. It can then be opened in a different editor from the .rc file without having its own entry in the RDT, or causing the error condition of the .rc file to have two entries in the RDT.

    • Persisting information specific to a solution that is either shared or private so that when the solution is reloaded, the information is loaded at the same time.

      This is demonstrated in the sample. The sample could be extended, however, to include persisting notes at the project level as well. This is especially important for source code control where the controlling VSPackage wants to maintain project-specific information as well as solution-specific information. Since project files are usually text-based, they can be placed under source code control.

      This is one of the main schemes you can use for delayed loading of your VSPackage. The VSPackage doesn't have to load every time Visual Studio is open, but by persisting information in this way, you can guarantee that the information is loaded whenever that solution is opened.

    • Adding the Solution Notes feature to a specific solution.

      This can be extended to solutions that have extra modeling or other features that you design and implement. In that way, you can model a solution that is intended to manage creating enterprise-level application systems.

    • Extending the sample to allow notes to be written for each project by writing to the Project section of the .sln file.

      By placing notes within the project section, you can use the same property name for the information and the environment will know that it is intended to be associated with the project. You can do the same thing in the global solution sections, but then you need to have a method of deriving unique property names for each note. You have to derive a compound property name by concatenating a base name that is the same for all notes and the project name.

      An example of when it is necessary to save information for each note in the .sln file is if the solution and projects are under source code control. The source code control VSPackage needs to write project-specific information to the file. By placing the information under each project, the property name in the name-value pair can be the same. Otherwise, the VSPackage needs to derive a compound name for each project.

    • Using the automation extenders to view extra properties for the UI you implement in the Properties window.

    • Adding items to the Context menu.

      The sample adds a menu option and a submenu to the context menu of the solution node. In a similar manner, menu options can be added to the project context menu, or to elements of the main menu.

See Also

Other Resources

Solution Extender