使用下拉列表进行方法导航





0/5 (0投票)
一个易于使用、占空间小的方法 DDL 导航工具。
引言
这是源代码大纲工具 (Source Code Outliner Power Toy) 和类视图 (Class View) 的替代方案。它是一个加载项,在“帮助”菜单旁边放置一个方法下拉列表 (DDL)。选择一个方法即可跳转到代码中的相应位置,整行高亮显示,并将第一行滚动到代码窗口的顶部。
此项目运用了 VS.NET 2008 IDE 可扩展性。第一个版本是一个 VB6 项目,旨在为 MS Office IDE 提供相同的功能。我怀念 VS.NET 中的方法 DDL 功能。我在此发布该项目,以便其他人可以(自行承担风险)使用或根据自己的需求进行定制。
背景
方法 DDL 克服了标准 IDE 导航的不足之处。
- 标准的双 DDL 方法在导航方面很麻烦,需要从两个 DDL 中进行选择。
- 选择导航目标后,由于行未高亮显示,因此可能难以找到选定的行。
- 标准方法 DDL 包含已使用和未使用的函数,因此可能非常长。
方法 DDL 比源代码大纲工具占用的空间更少,并且比类视图更易于导航。
Using the Code
提供两个下载:安装程序和源代码。
安装和使用加载项
- 解压缩并运行 Setup.exe。(通过“添加/删除程序”进行卸载)。
- 打开 VS 时,您会在“帮助”DDL 旁边看到 DDL。(安装后第一次打开 VS 时,您可能会看到两个 DDL 实例。下次启动 VS 时,第二个 DDL 会消失。)
- 打开模块(标准或类)进行编辑时,DDL 列表会重新填充。
- 当您在源代码中添加或删除方法时,列表会更新。
- 下拉方法列表并选择一个方法即可导航到目标方法的首行。
- 代码窗格会滚动(如果可能),以便将目标方法的首行置于窗格的顶部。
以下内容是为有兴趣修改/处理代码的开发人员准备的
源代码项目是针对 VS2008 中的 VB.NET。解压缩到您的 Visual Studio 2008 Projects 文件夹。源代码设置为在调试模式下运行,并使用一个特殊的 .addin 文件。这个特殊的 .addin 文件名为 "Proc_DDL - For Testing.AddIn",需要放置在 "C:\Documents and Settings\%USERNAME%\My Documents\Visual Studio 2008\Addins" 目录下。您需要将特殊 .addin 文件从 Debug_Addin zip 包中解压缩到 Addins 文件夹。在调试和发布模式下,只有 .addin 文件中的 Assembly 节点不同;示例如下。请确保已通过“添加/删除程序”卸载已安装的版本;如果您计划在调试模式下使用该项目,请用 VS2008 打开 .sln 文件。
<Assembly>C:\Documents and Settings\%USERNAME%\My Documents\Visual
Studio 2008\Projects\Proc_DDL\Proc_DDL\bin\Proc_DDL.dll</Assembly>
可安装版本使用一个不同的 .addin 文件,其 Assembly
行如下所示:
<Assembly>Proc_DDL_Addin\Proc_DDL.dll</Assembly>
这会将加载项 DLL 定位到目标加载项文件夹的 Proc_DDL_Addin 文件夹中,在我的情况下是:
[PersonalFolder]\Visual Studio 2008\Addins
其中 [PersonalFolder] 是 C:\Documents and Settings\%USERNAME%\My Documents(安装程序项目中的默认位置)。
如果需要将项目从调试模式切换回发布模式,则需要特别注意 .addin 文件。对于调试模式,请使用 "Proc_DDL - For Testing.AddIn"。对于发布模式,请将 "Proc_DDL - For Testing.AddIn" 重命名为 "Proc_DDL - For Testing.AddIn_",以便发布版本 "Proc_DDL.AddIn" 可以正常工作。将此过程反过来即可切换回调试模式。.addin 文件指定了 .dll 的位置。"Proc_DDL - For Testing.AddIn" 指定了调试信息所在的项目文件夹。"Proc_DDL.Addin" 指定了安装程序项目中的目标安装文件夹,在本例中是 "[PersonalFolder]\Visual Studio 2008\Addins\Proc_DDL"。两个 .addin 文件实际上都放置在 "[PersonalFolder]\Visual Studio 2008\Addins" 目录下。
- 为了进行测试/调试,“Proc_DDL - For Testing.AddIn”必须是活动的 .addin 文件。
- 安装会将 "Proc_DDL.Addin" 放入 "[PersonalFolder]\Visual Studio 2008\Addins" 目录下。
如果两个 .addin 文件都处于活动状态,则方法 DDL 将无法正常工作。因此,当您安装加载项以供“发布”使用时,需要重命名测试版本的 .addin 文件。
Carlos Quintero,MzTools,对 .addin 文件位置进行了详细的讨论,请参阅 Visual Studio 加载项的默认 .AddIn 文件位置。 对于 MzTools,国际化需要不同类型的 DLL 定位器,因此注册表中包含 MzTools 的 SatelliteDLLName 和 Path 信息(使用 RegAsm 注册)。
如果您计划修改源代码,请访问 MSDN 库,在 Visual Studio 2008 下找到“Visual Studio 自动化和可扩展性”,子主题“演练:调试加载项项目”。
在调试模式下运行项目需要将配置设置为“Debug”,然后在“工具/选项”中,展开“调试”节点,然后在“常规”下,清除“启动时无用户代码时发出警告”。这可以防止在测试过程中出现烦人的警告。无论警告如何,测试运行都可以正常工作(只要 .addin 文件配置正确)。
关注点
在 VB6 版本为 MS Office IDE 时,我无法访问 IDE 事件,因此我使用了一个“刷新”按钮来重新填充方法 DDL。VS IDE 事件暴露了方法 DDL 的两个重要改进:窗口和代码模型事件(没有这些事件,就需要一个“刷新”按钮,就像在 MS Office IDE 中一样)。
可以探索的途径有:
- IDE 事件,在 VS 可扩展性中非常丰富。
- 菜单栏和控件,以及
- 代码模型导航、窗格和文本管理。
要访问目标事件,请从 IDTExtensibility2.OnConnection
开始,该事件在 Visual Studio 的 [新建>项目>其他项目类型] 菜单下选择 Extensibility 类型项目时进行连接。需要进行一系列类型转换,从通用的连接对象变量 (oApp
) 降级到 Events2
,后者是 oWinEvents
和 oCodeModelEvents
所必需的。(我在很大程度上依赖 MSDN 获取代码示例。)
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)
在 VS IDE 中必须正常工作的事件对象必须是公共的,并且事件的实现方式如下面的代码段所示:
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
pb_ProcDDLStarted
是一个标志,用于确保只插入一个 DDL;它在类初始化期间被设置为 False
。
如果您想重新定位或调整方法 DDL 的大小,可以通过更改 cbControl_Help
来重新定位,也可以根据需要调整 cbComboBox
的宽度和下拉行数。
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 & QueryStatus when there's a Click Event
' which conforms to previous convention,
'??? ??? Not to mention it works as before
' (Exec & QueryStatus vaguely documented IMHO)
cbComboBox = CType(cbControls.Add(MsoControlType.msoControlComboBox), _
CommandBarComboBox)
Try
With cbComboBox
.Enabled = False
.Width = 300
.DropDownLines = 70
End With
oWinEvents_WindowActivated
如果 window.kind
是 "Document",则会调用一个刷新子程序来重新填充方法 DDL。OnCodeElement_Added
和 OnCodeElement_Deleted
处理添加和删除方法后的刷新。OnCodeElement_Changed
不是必需的,请参见第 284 行(如果代码发生更改,则会自动处理起始点)(我在注释中保留了 OnCodeElement_Changed
,以防您想使用它)。
(我还保留了刷新按钮的代码,以防您想尝试一下。)
刷新方法
从检查 sb_Refresh
开始。sb_OutlineCode
和 sb_OutlineElement
填充 oTbl
,后者由 sb_PopulateCombobox
使用。大纲功能会遍历文件代码模型,然后递归遍历代码元素以捕获所有函数名称。
转到 DDL 选择
在 OnConnection
中连接 cbComboBox
来处理方法的选择,请参阅上面的 pb_ProcDDLStarted
块。代码非常直接,除了使用了 MsoControlType.msoControlComboBox
。在 Visual Studio 中使用 MS Office 控件类型对我来说似乎有些奇怪。
sb_OutlineCode
再次使用,但搜索功能移动到所选方法的起始点,选择整行,然后尝试将函数起始点移动到窗格的顶部。如果代码被折叠,则存在一个副作用;当点击完全选中行的 + 号时,展开的部分将被全部选中。以下代码执行了移动到起始点、行选择和代码窗格调整操作。
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
历史
- 首次发布:2009.07.23。
- Beta 测试:2009.07.27:David Larson 报告了加载项初始使用时的两个 DDL。后续使用加载项时只有一个 DDL。尽管我们采取了特别措施来防止出现多个 DDL,但 VS IDE 在首次使用时会两次触发加载项的
onConnection
。在测试期间,我也看到了相同的初始两个 DDL。 - Beta 测试:2009.07.27。该加载项与 VS2008 Express Edition 不兼容。
- 2009.08.07:添加了表单设计器处理程序。加载项没有跳过设计文档的大纲。
- 2009.08.07:在 WPF 中进行了测试,以确保跳过 XAML 文档的大纲。