最后我发现了如何绑定到项目属性更改事件。需要实现IVsHierarchy接口,然后实现OnPropertyChanged事件。还需要枚举打开的项目,并一一绑定到它们的属性变化。请参见下面的示例。
public ref class Hierarchy: public IVsHierarchyEvents
{
private:
IVsHierarchy^ TargetHierarchy;
unsigned int TargetHierarchyCookie;
public:
Hierarchy(IVsHierarchy^ THierarchy)
{
TargetHierarchy = THierarchy;
TargetHierarchy->AdviseHierarchyEvents(this, TargetHierarchyCookie);
}
virtual int OnPropertyChanged(unsigned int itemid, int propid, unsigned int flags)
{
// your code here
}
...
};
public ref class Connect : public IDTExtensibility2, public IDTCommandTarget
{
private:
List<Hierarchy^>^ Hierarchies;
...
public:
virtual void OnConnection(...)
{
appObject = dynamic_cast<DTE2^>(Application);
addInInstance = dynamic_cast<AddIn^>(AddInInst);
...
// obtain the service provider
OLE::Interop::IServiceProvider^ SProvider = safe_cast<OLE::Interop::IServiceProvider^>(appObject);
Guid Sol_GuidService = (Guid)(SVsSolution::typeid)->GUID;
Guid Sol_riid = (Guid)(SVsSolution::typeid)->GUID;
IntPtr Sol_ppvObject;
// obtain the solution object
if (SProvider->QueryService(Sol_GuidService, Sol_riid, Sol_ppvObject)==VSConstants::S_OK && IntPtr::Zero!=Sol_ppvObject)
{
IVsSolution^ Sol = safe_cast<IVsSolution^>(Marshal::GetObjectForIUnknown(Sol_ppvObject));
IEnumHierarchies^ EnumHierarchies = nullptr;
Guid ProjectGUID = Guid("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}");
// enumerate through the projects and bind the project changed events
if (Sol->GetProjectEnum((unsigned int)(__VSENUMPROJFLAGS::EPF_MATCHTYPE | __VSENUMPROJFLAGS::EPF_ALLPROJECTS), ProjectGUID, EnumHierarchies)==VSConstants::S_OK && EnumHierarchies!=nullptr)
{
UInt32 pceltFetched;
array<IVsHierarchy^>^ rgelt = gcnew array<IVsHierarchy^>(1){nullptr};
for (EnumHierarchies->Reset(); EnumHierarchies->Next(1, rgelt, pceltFetched)==VSConstants::S_OK && pceltFetched==1; )
{
Hierarchy^ NewHierarchy = gcnew Hierarchy(rgelt[0]);
Hierarchies->Add(NewHierarchy);
}
}
}
}
...
};