![]() |
||||
This article discusses a performance problem that happens when an add-in for Visual Studio 2010 tries to get a CommandbarPopup by name using DTE.CommandBars[name] such as DTE.CommandBars["Tools"] to retrieve the "Tools" commandbar of the menu bar. This problem did not happen in Visual Studio 2008. More Information Visual Studio provides several kinds of commandbars: menu bars (such as the main menu of Visual Studio), toolbars (such as the "Standard" toolbar, context menus (such as the context menu of the code window) and commandbar popups (commandbars inside other commandbar, such as the "Tools" menu on the main menu of Visual Studio). Commandbar popups are special: a Commandbar contains controls (CommandBar.Controls collection) and each control is of the type CommandBarControl, which can be a button (CommandBarButton type), or a commandbar popup (CommandBarPopup type). The CommandBarPopup type has the CommandBar property to get its commandbar. The automation model of Visual Studio (EnvDTE) provides the EnvDTE.DTE.CommandBars collection, which you can use to get the menu bar, toolbar or a context menu knowing its name (see the article HOWTO: Guessing the name of a command bar to add a custom menu entry in Visual Studio .NET add-ins). However, the DTE.CommandBars collection should not be used to get a CommandBarPopup for the following reasons:
There are two correct ways to locate a commandbar popup:
The following add-in provides the code to reproduce the performance problem of Visual Studio 2010 locating the "Tools" commandbar popup in the DTE.CommandBars collection. You will notice that it takes several seconds:
using System;
using Microsoft.VisualStudio.CommandBars;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using System.Windows.Forms;
public class MyAddIn : Extensibility.IDTExtensibility2
{
private EnvDTE.DTE applicationObject;
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
try
{
applicationObject = (EnvDTE.DTE)application;
switch (connectMode)
{
case ext_ConnectMode.ext_cm_UISetup:
// Do nothing for this add-in with temporary user interface
break;
case ext_ConnectMode.ext_cm_Startup:
// The add-in was marked to load on startup
// Do nothing at this point because the IDE may not be fully initialized
// Visual Studio will call OnStartupComplete when fully initialized
break;
case ext_ConnectMode.ext_cm_AfterStartup:
// The add-in was loaded by hand after startup using the Add-In Manager
// Initialize it in the same way that when is loaded on startup
AddTemporaryUI();
break;
}
}
catch (System.Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString());
}
}
public void OnStartupComplete(ref System.Array custom)
{
AddTemporaryUI();
}
public void AddTemporaryUI()
{
CommandBar toolsCommandBar = null;
CommandBars commandBars = null;
System.DateTime t1, t2;
try
{
commandBars = (CommandBars)applicationObject.CommandBars;
t1 = System.DateTime.Now;
toolsCommandBar = commandBars["Tools"];
t2 = System.DateTime.Now;
MessageBox.Show(t2.Subtract(t1).TotalMilliseconds.ToString() + " milliseconds");
}
catch (System.Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString());
}
}
public void OnDisconnection(Extensibility.ext_DisconnectMode RemoveMode, ref System.Array custom)
{
}
public void OnBeginShutdown(ref System.Array custom)
{
}
public void OnAddInsUpdate(ref System.Array custom)
{
}
}
Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
Imports System.Windows.Forms
Public Class Connect
Implements Extensibility.IDTExtensibility2
Private applicationObject As EnvDTE.DTE
Public Sub OnConnection(ByVal application As Object, ByVal connectMode _
As Extensibility.ext_ConnectMode, ByVal addInInst As Object, _
ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnConnection
Try
applicationObject = CType(application, EnvDTE.DTE)
Select Case connectMode
Case ext_ConnectMode.ext_cm_UISetup
' Do nothing for this add-in with temporary user interface
Case ext_ConnectMode.ext_cm_Startup
' The add-in was marked to load on startup
' Do nothing at this point because the IDE may not be fully initialized
' Visual Studio will call OnStartupComplete when fully initialized
Case ext_ConnectMode.ext_cm_AfterStartup
' The add-in was loaded by hand after startup using the Add-In Manager
' Initialize it in the same way that when is loaded on startup
AddTemporaryUI()
End Select
Catch e As System.Exception
System.Windows.Forms.MessageBox.Show(e.ToString)
End Try
End Sub
Public Sub OnStartupComplete(ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnStartupComplete
AddTemporaryUI()
End Sub
Public Sub AddTemporaryUI()
Dim toolsCommandBar As CommandBar
Dim commandBars As CommandBars
Dim t1, t2 As Date
Try
commandBars = DirectCast(applicationObject.CommandBars, CommandBars)
t1 = Date.Now
toolsCommandBar = commandBars.Item("Tools")
t2 = Date.Now
MessageBox.Show(t2.Subtract(t1).TotalMilliseconds & " milliseconds")
Catch e As System.Exception
System.Windows.Forms.MessageBox.Show(e.ToString)
End Try
End Sub
Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnDisconnection
End Sub
Public Sub OnBeginShutdown(ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnBeginShutdown
End Sub
Public Sub OnAddInsUpdate(ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnAddInsUpdate
End Sub
End Class
Related articles
Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this
|
| Copyright © 2000-2013 MZTools Software. All Rights Reserved. Legal Notice |