Reputation: 799
I'm developing a Visual Studio 2010 Add-In and I'm stuck at this moment. I would like to receive notification about property changes of specific project items. For example I need to know if a new Form (winform) was added into my project.
There are 2 possibilities how to add a form into the project in Visual Studio 2010:
You can simply Add a new Form item through the context menu. In this case the ProjectItemAdded event is thrown by the IDE. The problem is, that at that time the new form is recognized as eFileTypeCppHeader and not eFileTypeCppForm.
The second option is to change the FileType property of a Header file to "C++ Form" through the property tab. There is no event which notifies the Add-In about this property change.
So, how can my Add-In know the property of an ProjectItem was changed?
Upvotes: 2
Views: 509
Reputation: 799
Finally I found out how to bind to the project property changed event. It is necessary to implement the IVsHierarchy interface and then implement the OnPropertyChanged event. It is also necessary to enumerate through the opened projects and bind to their property changes one by one. See the example bellow.
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);
}
}
}
}
...
};
Upvotes: 1