Answered by:
Add item properties in Visual Studio 2019 project system

Question
-
I am trying to add properties to an item type in a custom Visual Studio 2019 project. I am using the new CPS project system and created a Package. CPS supports Xaml Rule files for hooking up item properties but this system is just not going to work for my solution because they are static rules.
I need to show different properties for a single item type based on another property. It is a similar functionality that used to be in XNA and I also had this working in the old project system like 10 years ago. For example, I have Content item types but one item has a property Type=A, so it has one string property, another Content item had Type=1, so it has one integer property.
I have tried using EnvDTE.IExtenderProvider but after following code samples my provider is never called. I believe this is because it is no longer supported in VS 2019. The page for EnvDTE.IExtenderProvider does not list it, only 2015 and 2017.
Another solution I have tried is swapping out the Property Browser with a custom control but my custom property control is only swapped out when I focus a custom tool box window. I created a MyPropertyBrowser and inside MyToolWindow I hook up the browser object.
Dim trackSel = CType(GetService(GetType(SVsTrackSelectionEx)), IVsTrackSelectionEx) Dim guidBrowser = GetType(MyPropertyBrowser).GUID.ToString("B") trackSel.OnElementValueChange(CUInt(VSConstants.VSSELELEMID.SEID_PropertyBrowserSID), 0, guidBrowser)
Inside MyPropertyBrowser I use SVsShellMonitorSelection.GetCurrentSelection to get the selected item. Is there a way to get MyPropertyBrowser to show without a custom tool box window? I suspect it is not possible because of the scope of SVsTrackSelectionEx, and it must be called from within the solution explorer.
Alternatively, is there a way to update the property browser when certain items are selected in the solution explorer? Possibly some way to add properties once a selection is detected.
- Edited by MannyMarqz Thursday, April 16, 2020 7:07 AM
Thursday, April 16, 2020 7:06 AM
Answers
-
One trick I found was to listen for selection events using SVsShellMonitorSelection and then hijack the solution explorer to change the selection.
If Not Me.mUpdatingSelection Then Me.mUpdatingSelection = True Try Dim shell = TryCast(Microsoft.VisualStudio.Shell.Package.GetGlobalService(GetType(SVsUIShell)), IVsUIShell) Dim window As IVsWindowFrame = Nothing shell.FindToolWindow(CUInt(__VSFINDTOOLWIN.FTW_fFrameOnly), New Guid(ToolWindowGuids.SolutionExplorer), window) Dim frame As Object = Nothing window.GetProperty(__VSFPROPID.VSFPROPID_SPFrame, frame) Dim serviceProvider = New ServiceProvider(TryCast(frame, OLE.Interop.IServiceProvider)) Dim trackSelection = TryCast(serviceProvider.GetService(GetType(STrackSelection)), IVsTrackSelectionEx) Dim selectionContainer As New Shell.SelectionContainer Dim selectedItems As New ArrayList selectedItems.Add(New ContentItem) selectionContainer.SelectedObjects = selectedItems trackSelection.OnSelectChange(selectionContainer) Finally Me.mUpdatingSelection = False End Try End If
However, I did manage to find the proper solution although I have not found any documentation for it. The trick is to implement and export an IExtenderCATIDProvider.
<Export(GetType(IExtenderCATIDProvider))> <AppliesTo(Constants.UniqueCapability)> Friend Class MyExtenderCATIDProvider : Implements IExtenderCATIDProvider <ImportingConstructor> Friend Sub New(unconfiguredProject As MyUnconfiguredProject) End Sub Friend Function GetExtenderCATID(extenderCATIDType As ExtenderCATIDType, treeNode As IProjectTree) As String Implements IExtenderCATIDProvider.GetExtenderCATID Select Case extenderCATIDType Case ExtenderCATIDType.AutomationProjectItem : Return Constants.ContentItemExtenderCatIdGuid.ToString("B") Case ExtenderCATIDType.FileBrowseObject : Return Constants.ContentItemExtenderCatIdGuid.ToString("B") End Select Return Nothing End Function End Class
Then code your extender provider like explained here
https://lehmamic.wordpress.com/2013/07/10/extending-cs-file-properties-in-a-vspackage/
- Edited by MannyMarqz Sunday, April 19, 2020 5:58 AM
- Marked as answer by MannyMarqz Sunday, April 19, 2020 5:58 AM
Sunday, April 19, 2020 5:57 AM
All replies
-
It would appear that this is not possible with CPS VSProjectSystem. The SimpleHierarchyNode class creates objects that ultimately return a DynamicTypeBrowseObject which uses the IRule implementation. There does not seem to be any way of accomplishing this.
I will need to create a new tool window to display other properties. Unless there is a way to host a custom control inside the PropertyBrowser for individual tree items. Or a way to extend the properties.
Thursday, April 16, 2020 6:34 PM -
Hi MannyMarqz,
Welcome to MSDN forum.
Maybe you can try to use ITrackSelection Interface, which can help you expose custom properties to properties window.
Best Regards,
Dylan
MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com
Friday, April 17, 2020 3:46 AM -
One trick I found was to listen for selection events using SVsShellMonitorSelection and then hijack the solution explorer to change the selection.
If Not Me.mUpdatingSelection Then Me.mUpdatingSelection = True Try Dim shell = TryCast(Microsoft.VisualStudio.Shell.Package.GetGlobalService(GetType(SVsUIShell)), IVsUIShell) Dim window As IVsWindowFrame = Nothing shell.FindToolWindow(CUInt(__VSFINDTOOLWIN.FTW_fFrameOnly), New Guid(ToolWindowGuids.SolutionExplorer), window) Dim frame As Object = Nothing window.GetProperty(__VSFPROPID.VSFPROPID_SPFrame, frame) Dim serviceProvider = New ServiceProvider(TryCast(frame, OLE.Interop.IServiceProvider)) Dim trackSelection = TryCast(serviceProvider.GetService(GetType(STrackSelection)), IVsTrackSelectionEx) Dim selectionContainer As New Shell.SelectionContainer Dim selectedItems As New ArrayList selectedItems.Add(New ContentItem) selectionContainer.SelectedObjects = selectedItems trackSelection.OnSelectChange(selectionContainer) Finally Me.mUpdatingSelection = False End Try End If
However, I did manage to find the proper solution although I have not found any documentation for it. The trick is to implement and export an IExtenderCATIDProvider.
<Export(GetType(IExtenderCATIDProvider))> <AppliesTo(Constants.UniqueCapability)> Friend Class MyExtenderCATIDProvider : Implements IExtenderCATIDProvider <ImportingConstructor> Friend Sub New(unconfiguredProject As MyUnconfiguredProject) End Sub Friend Function GetExtenderCATID(extenderCATIDType As ExtenderCATIDType, treeNode As IProjectTree) As String Implements IExtenderCATIDProvider.GetExtenderCATID Select Case extenderCATIDType Case ExtenderCATIDType.AutomationProjectItem : Return Constants.ContentItemExtenderCatIdGuid.ToString("B") Case ExtenderCATIDType.FileBrowseObject : Return Constants.ContentItemExtenderCatIdGuid.ToString("B") End Select Return Nothing End Function End Class
Then code your extender provider like explained here
https://lehmamic.wordpress.com/2013/07/10/extending-cs-file-properties-in-a-vspackage/
- Edited by MannyMarqz Sunday, April 19, 2020 5:58 AM
- Marked as answer by MannyMarqz Sunday, April 19, 2020 5:58 AM
Sunday, April 19, 2020 5:57 AM