【问题标题】:How can I track property changes of a project item through visual studio Add-In如何通过 Visual Studio 插件跟踪项目项的属性更改
【发布时间】:2013-03-10 21:23:44
【问题描述】:
我正在开发一个 Visual Studio 2010 加载项,但此时我陷入了困境。我想收到有关特定项目项目属性更改的通知。例如,我需要知道是否在我的项目中添加了新表单(winform)。
在 Visual Studio 2010 中将表单添加到项目中有两种可能性:
您可以通过上下文菜单简单地添加一个新的表单项。在这种情况下,IDE 会引发 ProjectItemAdded 事件。问题是,当时新表单被识别为 eFileTypeCppHeader 而不是 eFileTypeCppForm。
第二个选项是通过属性选项卡将 Header 文件的 FileType 属性更改为“C++ Form”。没有通知加载项有关此属性更改的事件。
那么,我的加载项如何知道 ProjectItem 的属性已更改?
【问题讨论】:
标签:
.net
visual-studio-2010
add-in
【解决方案1】:
最后我发现了如何绑定到项目属性更改事件。需要实现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);
}
}
}
}
...
};