如何:响应特定项目中的事件 (Visual C#)
自动化模型包括可用于响应 Visual Studio 集成开发环境 (IDE) 中的环境事件的对象。 在特定于 Visual C# 和 Visual Basic 项目的 VSLangProj 和 VSLangProj80 中定义了环境事件。 例如,在向 Visual Basic 项目中添加或从中移除一个导入对象时,会引发 ImportsEvents。
此示例使用 Visual C# 将某类项目特定的 ReferencesEvents 事件处理程序添加到外接程序项目中。 在更改引用以及在 Visual C# 或 Visual Basic 项目中添加或移除引用时,将引发 ReferencesEvents。
备注
显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您现用的设置或版本。这些过程是在“常规开发设置”处于活动状态时开发的。若要更改设置,请在“工具”菜单上选择“导入和导出设置”。有关更多信息,请参见 Visual Studio 设置。
使用 Visual C# 处理与引用相关的事件
在 Visual C# 中创建 Visual Studio 外接程序项目。
向 Connect.cs 文件顶部添加 using VSLangProj;。
在**“项目”菜单上,单击“添加引用”,再单击“.NET”选项卡,然后选择第一个“VSLangProj”,并单击“确定”**。
在 Connect 类中,初始化一个变量以处理 ReferencesEvents 对象,初始化另一个变量以处理 OutputWindowPane。
private DTE2 _applicationObject; private AddIn _addInInstance; private VSLangProj.ReferencesEvents refEvents; private OutputWindowPane outputWinPane;
在此示例中,变量被命名为 refEvents。
自动化模型中的其他对象与特定于项目的其他类型的事件相关。 例如,在向 Imports 集合添加导入或从中移除导入时会引发 ImportsEvents。 BuildManagerEvents 应用于根据自定义工具的输出生成的临时程序集的相关事件。 有关 BuildManager 对象的更多信息,请参见 BuildManager 对象介绍。 有关特定于项目类型的事件的完整列表,请参见 事件对象(特定于项目的类型);有关常规自动化事件的列表,请参见 自动化事件对象。
在 OnConnection 方法中,初始化一个变量以截获事件。 在此示例中,变量被命名为 events。
EnvDTE80.Events2 events = (EnvDTE80.Events2)_applicationObject.Events;
在 OnConnection 方法中,初始化 OutputWindow 变量。
OutputWindow outputWindow = (OutputWindow)_applicationObject.Windows.Item (Constants.vsWindowKindOutput).Object; outputWinPane = outputWindow.OutputWindowPanes.Add ("ReferencesEvents Event Information");
此外,在 OnConnection 方法中检索来自自动化模型的事件对象。
refEvents = (VSLangProj.ReferencesEvents)events.GetObject ("CSharpReferencesEvents");
在本示例中,ReferencesEvents 特定于 Visual C# 项目。 若要响应 Visual Basic 特定的事件,请将字符串 CSharpReferencesEvents 替换为 VBReferencesEvents。 有关如何确定应为特定于不同类型的项目的事件使用哪些字符串的更多信息,请参见 事件对象(特定于项目的类型)。
使用 += 运算符连接到步骤 3 中检索的事件对象公开的每个委托。 例如,若要连接 ReferenceAdded 事件所公开的委托,请使用:
refEvents.ReferenceAdded += new _dispReferencesEvents_ReferenceAddedEventHandler (this.ReferenceAdded);
为与事件对象相关的每个事件添加过程。 例如,若要处理添加引用时发生的事件,请使用:
public void ReferenceAdded( VSLangProj.Reference addedRef ) { outputWinPane.OutputString( "ReferencesEvents.ReferenceAdded" + "\n" ); outputWinPane.OutputString( "The reference to " + addedRef.Name + " was added." + "\n" ); }
如果是 ReferencesEvents,则必须为如下内容定义事件:
和
下面示例中的完整列表包括这些事件。
最后,为了防止在关闭外接程序后 Visual Studio 继续监视与窗口相关的事件而减慢系统的运行速度,应禁用事件处理。 在 Visual C# 中,这通过使用 -= 运算符来完成。 例如,若要禁用 ReferenceAdded 的事件处理,请使用:
refEvents.ReferenceAdded -= new _dispReferencesEvents_ReferenceAddedEventHandler (this.ReferenceAdded);
这样,无论是关闭外接程序还是在外接程序仍然运行的情况下关闭 IDE,都会关闭事件处理。 关闭 IDE 后,所有正在运行的外接程序将首先自动关闭。
示例
下面的示例是一个简单的 Visual Studio 外接程序,它演示如何在 Visual Studio 中截获和处理 Visual C# 引用事件。 每当发生引用事件时,就会向**“输出”**窗口发送一则通知消息。
using System;
using Microsoft.VisualStudio.CommandBars;
using Extensibility;
using EnvDTE;
using EnvDTE80;
using VSLangProj;
public Connect()
{
}
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
// Retrieve the event objects from the automation model.
EnvDTE80.Events2 events =
(EnvDTE80.Events2)_applicationObject.Events;
// Send event messages to the Output window.
OutputWindow outputWindow =
(OutputWindow)_applicationObject.Windows.Item
(Constants.vsWindowKindOutput).Object;
outputWinPane =
outputWindow.OutputWindowPanes.Add
("ReferencesEvents Event Information");
// Retrieve the event objects from the automation model.
refEvents = (VSLangProj.ReferencesEvents)
events.GetObject("CSharpReferencesEvents");
// Connect to each delegate exposed from each object
// retrieved above.
refEvents.ReferenceAdded += new
_dispReferencesEvents_ReferenceAddedEventHandler
(this.ReferenceAdded);
refEvents.ReferenceChanged += new
_dispReferencesEvents_ReferenceChangedEventHandler
(this.ReferenceChanged);
refEvents.ReferenceRemoved += new
_dispReferencesEvents_ReferenceRemovedEventHandler
(this.ReferenceRemoved);
}
public void OnDisconnection(Extensibility.ext_DisconnectMode
disconnectMode, ref System.Array custom)
{
// If the delegate handlers have been connected, then
// disconnect them here.
// If you do not do this, the handlers may still
// fire because they have not been garbage collected.
if (refEvents != null)
{
refEvents.ReferenceAdded -= new
_dispReferencesEvents_ReferenceAddedEventHandler
(this.ReferenceAdded);
refEvents.ReferenceChanged -= new
_dispReferencesEvents_ReferenceChangedEventHandler
(this.ReferenceChanged);
refEvents.ReferenceRemoved -= new
_dispReferencesEvents_ReferenceRemovedEventHandler
(this.ReferenceRemoved);
}
}
// References related events.
public void ReferenceRemoved( VSLangProj.Reference removedRef )
{
outputWinPane.OutputString( "ReferencesEvents.ReferenceRemoved"
+ "\n" );
outputWinPane.OutputString( "The reference to " + removedRef.Name
+ " was removed." + "\n" );
}
public void ReferenceChanged( VSLangProj.Reference changedRef )
{
outputWinPane.OutputString( "ReferencesEvents.ReferenceChanged"
+ "\n" );
outputWinPane.OutputString( "The reference to " + changedRef.Name
+ " was changed." + "\n" );
}
public void ReferenceAdded( VSLangProj.Reference addedRef )
{
outputWinPane.OutputString( "ReferencesEvents.ReferenceAdded" +
"\n" );
outputWinPane.OutputString( "The reference to " + addedRef.Name
+ " was added." + "\n" );
}
public void OnAddInsUpdate(ref System.Array custom)
{
}
public void OnStartupComplete(ref System.Array custom)
{
}
public void OnBeginShutdown(ref System.Array custom)
{
}
private DTE2 _applicationObject;
private AddIn _addInInstance;
private VSLangProj.ReferencesEvents refEvents;
private OutputWindowPane outputWinPane;
}}
编译代码
若要编译此代码,请在 Visual C# 中新建 Visual Studio 外接程序项目,然后用该示例中的代码替换 Connect 类的代码。 有关如何运行外接程序的信息,请参见如何:使用外接程序管理器控制外接程序。