Click here to Skip to main content
15,894,343 members
Articles / Programming Languages / Visual Basic

Methods Navigation with a Drop-Down List

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
7 Aug 2009CPOL7 min read 20.4K   315   5  
An easy to use, low real estate Methods DDL navigation tool.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--------------------------------------------------------------------------->  
<!--                        Style Sheet                             	   -->
<html>
<head>
<title>Methods Navigation Project</title>
<link rel="stylesheet" type="text/css" href="http://www.codeproject.com/App_Themes/NetCommunity/CodeProject.css">
<style type="text/css">
.style1 {
	border-style: solid;
	border-width: 1px;
}
</style>
</head>
<body style="margin-left: 7px; margin-right: 7px">
<!-------------------------------     STEP 1      --------------------------->
<!--  Fill in the details (CodeProject will reformat this section for you) -->
<pre>
Title:       Methods Navigation with a Drop-Down List
Author:      Barry G. Hynum, Ph.D. -- MaxQual Consulting 
Email:       BHynum@cox.net
Member ID:   2917721
Language:    VB.Net
Platform:    Windows, VS 2008
Technology:  VS IDE Extensibility
SWE Level:   Advanced
User Level:  VS Developers
Description: An easy to use, low real estate methods DDL navigation tool.
License:     CPOL
</pre>
<!-------------------------------     STEP 2a      --------------------------->
<!--  Include download information.                                         -->
<ul class=download>
<li><A href="Installation_Kit.zip">Methods DDL Installer - 429 Kb </A></li>
<li><A href="Proc_DDL_Debug.zip">Methods DDL Source - 980 Kb</A></li>
<li><A href="Debug_Addin.zip">Debug .addin file - 6 Kb</A></li>
</ul>

<!-------------------------------     STEP 2b      --------------------------->
<!--  Include sample image information.                                     --> 
<p><span class="style1"><IMG alt="Example of Methods DDL" src ="VB_Sample_3.jpg"></span></p>

<!-------------------------------     STEP 3      --------------------------->
<h2>Introduction</h2>

<p>This is an alternate to the Source Code Outliner Power Toy &amp; the Class View. It is an 
add-in that places a drop-down list (DDL) of methods next to the Help menu. 
Select a method &amp; jump to that spot in code, the full line is highlighted &amp; 
1st line is scrolled to the top of the code window.</p>

<p>This project exercises VS. Net 2008 IDE 
Extensibility. The 1st incarnation was a VB6 project to do the same DDL for MS 
Office IDE. I missed the methods DDL functionality in VS. Net.
I'm posting the project so others can either use <i>(at their own risk)</i> or 
customize for their own use.</p>
<!-------------------------------     STEP 4      --------------------------->
<h2>Background</h2>

<p>The Methods DDL overcomes shortcomings of the std. IDE navigation. </p>
<UL>
  <LI>The std. dual DDL approach is cumbersome for navigation, requiring selection from 2 DDL's. </LI>
  <LI>After selecting the navigation target, because the line is not highlighted, it can be difficult to find the selected line. </LI>
  <LI>The std. methods DDL has used &amp; unused methods so it can be quite long.</LI>
</UL>

<p>The Methods DDL takes less real estate than the Source Code Outliner Power Toy &amp; 
is simpler to navigate than the class viewer.</p>

<!-------------------------------     STEP 5      --------------------------->
<h2>Using the Code</h2>

<p>Two downloads are available: (1) an installer, and (2) source code. </p>
<P>To install &amp; use the addin: </P>
<UL>
  <LI>Unzip &amp; run Setup.exe. (Uninstall from Add/Remove Programs) </LI>
  <LI>When VS is opened, you'll see the DDL next to the Help DDM. (The 1st time VS is opened after the install, you may see 2 instances of the DDL. 
  The 2nd DDL will disappear the next time VS is started.)
  </LI>
  <LI>When a module (std or class) is open for editing, the DDL list repopulates </LI>
  <LI>The list is updated as you add or delete methods in your source code </LI>
  <LI>Drop down the list of methods &amp; select one to navigate to the 1st line of the target method</LI>
  <LI>The code pane scrolls if possible so that the first line of the target method is at the top of the pane</LI>
</UL>

<H4>The following is for developers interested in modifying/working with the code.</H4>
<p>The source code project is for VS 2008 in VB.Net. 
Unzip to your Visual Studio 2008 Projects folder. 
The source code is set up to run in debug &amp; uses a special .addin.
The special .addin is named "Proc_DDL - For Testing.AddIn" and needs to be placed in
"C:\Documents and Settings\<code>%USERNAME%</code>\My Documents\Visual Studio 2008\Addins".
You will need to unzip the special .addin from the Debug_Addin zip to the Addins folder.
Only the Assembly node in the .addin is different between debug &amp; release usage, examples below.
Be sure the installed version is uninstalled via Add/Remove Programs if you plan 
to use the project in debug mode then open the .sln with VS 2008.</p>

<pre>
&lt;Assembly&gt;C:\Documents and Settings\<code>%USERNAME%</code>\My Documents\Visual Studio 2008\Projects\Proc_DDL\Proc_DDL\bin\Proc_DDL.dll&lt;/Assembly&gt;
</pre>

<p>The installable uses a different .addin with an Assembly line like this:</p>
<pre>
&lt;Assembly&gt;Proc_DDL_Addin\Proc_DDL.dll&lt;/Assembly&gt;
</pre>
Which locates the AddIn dll in the Proc_DDL_Addin folder of the target AddIn folder, in my case:
<pre>
[PersonalFolder]\Visual Studio 2008\Addins
</pre>
Where [PersonalFolder] is C:\Documents and Settings\<code>%USERNAME%</code>\My Documents 
(Default Location in the setup project). 

<p>If you need to switch the project back 
from debug to release mode, special care is needed with the .addin files. For debug mode, use
"Proc_DDL - For Testing.AddIn". For release mode, rename "Proc_DDL - For Testing.AddIn" to 
"Proc_DDL - For Testing.AddIn_" so the release version "Proc_DDL.AddIn" will work. 
Reverse that process to go back to debug mode. The .addin specifies where the .dll is located. 
"Proc_DDL - For Testing.AddIn" specifies the project folder with debug info.
"Proc_DDL.Addin" specifies the target installation folder from the setup project, in this case 
"[PersonalFolder]\Visual Studio 2008\Addins\Proc_DDL". Both .addins are actually placed in 
"[PersonalFolder]\Visual Studio 2008\Addins" (1) for testing/debug "Proc_DDL - For Testing.AddIn"
must be the active .addin, (2) an install will put "Proc_DDL.Addin" in "[PersonalFolder]\Visual Studio 2008\Addins".
If both .addins are active, the Methods DDL will not work. Hence the renaming of the test version of .addin 
when you install the addin for "release" usage.</p>

<p>Carlos Quintero, MzTools, has a detailed discussion of the .addin locations, see
<A href="http://www.mztools.com/articles/2008/MZ2008001.aspx">
<i>Default .AddIn file locations for Visual Studio add-ins.</i></A> 
For MzTools, internationalization required
a different kind of dll locator so the registry has SatelliteDLLName &amp; Path info for MzTools 
(registered with RegAsm).</p>

<p>If you plan on modifying the source code, please visit the MSDN library, 
under Visual Studio 2008, find &quot;Visual Studio Automation and Extensibility,&quot; 
subtopic &quot;Walkthrough: Debugging an Add-in Project.&quot;</p>

<p>Running the project in debug requires setting the configuration to "Debug" and under Tools/Options, expand the 
Debugging node then under General clear "Warn if no user code on launch." This prevents an annoying warning popping up
during testing. Regardless of the warning, test runs worked fine (as long as the 
.addin is configured correctly).</p>

<!-------------------------------     STEP 6      --------------------------->
<h2>Points of Interest</h2>
<!--Did you learn anything interesting/fun/annoying while writing the code? Did you
do anything particularly clever or wild or zany?-->

<p>In the VB6 incarnation for the MS Office IDE, I was unable to get at IDE events 
so I used a refresh button to restock the DDL of methods.
The VS IDE Events exposed 2 important improvements for the methods DDL: windows &amp; code model events 
(without these events a refresh button would be needed as in the MS Office IDE).</p>

<p>Avenues of exploration are: </p>
<UL>
<LI>IDE events which are quite rich in VS Extensibility</LI>
<LI>Menu bars &amp; controls, and</LI>
<LI>The code model navigation, pane &amp; text management
</UL>

<p>To get at the target events, begin with IDTExtensibility2.OnConnection which gets wired up when 
the Extensibility type project gets selected under the [New&gt;Project&gt;Other Project Types] menu in Visual Studio.
A casting cascade is needed to go from general connection object variable (<code>oApp</code>) down to 
Events2 which is needed for 
<code>oWinEvents</code> &amp; <code>oCodeModelEvents</code>. (I relied on MSDN 
to get samples of much of this code.)</p>
<pre>
Public Sub OnConnection( _
        ByVal oApp As Object, _
        ByVal oConnectMode As ext_ConnectMode, _
        ByVal oThis_AddIn As Object, _
        ByRef custom As Array) _
            Implements IDTExtensibility2.OnConnection

        Dim oEvents2 As EnvDTE80.Events2

        oDTE2 = CType(oApp, DTE2)
        oAddIn = CType(oThis_AddIn, AddIn)

        oEvents2 = CType(oDTE2.Events, EnvDTE80.Events2)
        oWinEvents = CType(oEvents2.WindowEvents(Nothing), EnvDTE.WindowEvents)
        oCodeModelEvents = oEvents2.CodeModelEvents(Nothing)
</pre>

<p>The event objects that must work in the VS IDE need to be public withevents 
as implemented in the following code segment.</p>
<pre>
Public Class Connect
    Implements IDTExtensibility2
    Private oDTE2 As DTE2
    Private oAddIn As AddIn
    Public WithEvents oWinEvents As EnvDTE.WindowEvents
    Public WithEvents oCodeModelEvents As EnvDTE80.CodeModelEvents
    Public WithEvents cbComboBox As CommandBarComboBox
    'Public WithEvents cbButton As CommandBarButton '--- For exploration only
    Private oTbl As DataTable
    Private oDocCurrent As Document
</pre>

<p><code>pb_ProcDDLStarted</code> is a flag used to ensure that there is only one DDL insert, 
it is set to false during class initialization. 
<p>If you want to relocate or resize the Methods DDL, reposition by changing <code>cbControl_Help</code> 
as you like or the width &amp; drop down lines for <code>cbComboBox</code>.</p>
<pre>
If Not pb_ProcDDLStarted Then
   pb_ProcDDLStarted = True
      Dim oCommands As Commands2 = CType(oDTE2.Commands, Commands2)

      '--- Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
      Dim cbs As CommandBars = CType(oDTE2.CommandBars, CommandBars)
      Dim mbCommandBar As CommandBar = cbs.Item("MenuBar")

      '--- Find the Help command bar control on the MenuBar command bar:
      Dim cbControl_Help As CommandBarControl = mbCommandBar.Controls.Item("Help")
      Dim iCmdPosition As Integer = CInt(CType(cbControl_Help.Index, Long) + 1)

      Dim cbControls As CommandBarControls = mbCommandBar.Controls
      '??? Abit odd to be using a Microsoft.Office.Core enumeration
      'cbButton = CType(cbControls.Add(MsoControlType.msoControlButton), CommandBarButton)
      '??? Why use Exec &amp; QueryStatus when there's a Click Event which conforms to previous convention,
      '??? ??? Not to mention it works as before (Exec &amp; QueryStatus vaguely documented IMHO)
      cbComboBox = CType(cbControls.Add(MsoControlType.msoControlComboBox), CommandBarComboBox)

      Try
          With cbComboBox
               .Enabled = False
               .Width = 300
               .DropDownLines = 70
          End With
</pre>

<p><code>oWinEvents_WindowActivated</code> calls a refresh sub to repopulate the methods DDL if the window.kind is "Document."
<code>OnCodeElement_Added</code> &amp; <code>OnCodeElement_Deleted</code> handle refreshing after adding &amp; deleting methods. 
<code>OnCodeElement_Changed</code> was not necessary, see line 284 (If code changes, the start point is handled automatically)
(I left <code>OnCodeElement_Changed</code> in comments in case you want to use it).</p>

<p>(I also left in the code for a refresh button in the event that you want to play with that.)</p>

<H4>Refresh Method</H4>
<p>Start by examining <code>sb_Refresh</code>. <code>sb_OutlineCode</code> &amp; <code>sb_OutlineElement</code> 
populate <code>oTbl</code> which is used by <code>sb_PopulateCombobox</code>.
The outline functionality walks through the file code model then code elements recursively to capture 
all the function names.</p>

<h4>Go To DDL Selection</h4>
<p>Wiring up <code>cbComboBox</code> to handle the selection of a method is done in OnConnection, 
see <code>pb_ProcDDLStarted</code> block above.
The code is pretty straight forward except for the use of MsoControlType.msoControlComboBox. Use of MS 
Office control types in Visual Studio seemed a bit odd to me.</p>

<p><code>sb_OutlineCode</code> is used again except the search function moves to the start point of the selected method, 
selects the entire line, then attempts to move the start point for the function to the top of the pane. 
There is a side effect if the code is collapsed; when the + sign is clicked on a fully selected line, 
the expanded section is all selected. The following code does the move to start point, line select &amp; code pane adjustment.</p>

<pre>
If oCTElems.Item(i).Name = sProcName Then
    Dim oSel As TextSelection _
        = CType(oDocCurrent.Selection, TextSelection)

    Dim oTextPane As TextPane _
        = oSel.TextPane

    With oSel
        .MoveToPoint(oCTElems.Item(i).StartPoint)
        .SelectLine()
        oTextPane.TryToShow(oCTElems.Item(i).StartPoint, vsPaneShowHow.vsPaneShowTop)
    End With

End If
</pre>

<!-------------------------------     STEP 7      --------------------------->
<h2>History</h2>
<UL>
<LI>First Release 2009.07.23</LI>
<LI>Beta Test 2009.07.27 &gt;&gt; <A href="http://thesilverstream.com/default.aspx">David Larson</A> reported 2 DDLs for 
initial use of the addin. Subsequent uses of the addin only had 1 DDL. Despite special care to prevent more 
than 1 DDL, the VS IDE was firing the addin onConnection twice on the 1st use. 
During testing, I saw the same initial 2 DDLs.</LI>
<LI>Beta Test 2009.07.27 &gt;&gt; The addin does not work with VS 2008 Express Edition.</LI>
<LI>2009.08.07 &gt;&gt; Added handler for Forms Designer. Addin was not skipping 
outline for design documents.</LI>
<LI>2009.08.07 &gt;&gt; Tested in WPF to be sure outliner was skipped for xaml documents.</LI>
</UL>

<!-------------------------------     STEP 8      --------------------------->
<h2>Contact Info</h2>
<UL>
<LI><A href="mailto:BHynum@cox.net">Barry G. Hynum, Ph.D.</A></LI>
<LI><A href="http://www.MaxQualConsulting.com">MaxQual Consulting</A></LI>
</UL>

</body>

</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) MaxQual Consulting
United States United States
Specializing in databases & data transfer between applications including: web site DBs & desktop accounting. Extensive tool development, browse MaxQualConsulting.com.

Comments and Discussions