Skip to content

CPS - How To Conditionally show a property on a ProjectReference browse object based on the *referenced* project's properties? #384

Description

@ArZei

This is a copy of my report on developer community: https://developercommunity.visualstudio.com/t/CPSExtensibility---How-To-Conditionally/11124279

Greetings,

We are a third-party language extender in Visual Studio. We have a custom CPS-based project system (a .synproj project type) and we are trying to find out how to conditionally show a property/metadata under a project reference's properties window, as such:

Image

We would like to filter the visibility of this metadata so it shows only when the referenced project has a specific characteristic (in my case OutputType=RPS, but flexible and can be Capability based, etc.)

This is largely driven by the XAML rule below:

<?xml version="1.0" encoding="utf-8"?>
<!--Copyright, Microsoft Corporation, All rights reserved.-->
<Rule
    Name="ProjectReference"
    DisplayName="Project Reference"
    PageTemplate="custom"
    Description="Project Reference Properties"
    OverrideMode="Extend"
    xmlns="http://schemas.microsoft.com/build/2009/properties">

  <Rule.DataSource>
    <DataSource HasConfigurationCondition ="False" Persistence="ProjectFile" ItemType="ProjectReference" />
  </Rule.DataSource>

  <BoolProperty
      Name="Default"
      Visible="True"
      DisplayName="Default Repository"
      Description="Default Repository" />
</Rule>

Approaches tried and results:

  1. XAML rule using AppliesTo or VisibilityCondition
    Doesn't work because this filters based on the referencing project, not the referenced project, and the rule is loaded up-front before any kind of logic we can run on the project references.

  2. Property page factory via IPropertyPageUIFactoryProvider
    Implemented a property page factory, MEF imported and ProjectCapability controlled. Tried to provide our own custom property view. Doesn't seem to hit the property windows under CPS.

  3. Design-time item reclassification of ProjectReference into a custom type (ex. RepositoryReference)
    Created a target (gated on DesignTimeBuild/BuildingInsideVisualStudio, BeforeTargets="ResolveProjectReferences") reclassifies qualifying ProjectReference items to a custom RepositoryReference item type, with a matching BrowseObject-context XAML rule carrying the property. Verified via design-time build log that the reclassification runs and produces the correct item. The property still does not appear, and the reference node's browse object remains bound to the built-in ProjectReference type

  4. Automation extender via IExtenderCATIDProvider
    Implemented and exported the provider; it returns a CATID for ExtenderCATIDType.ReferenceBrowseObject. Registered an IExtenderProvider under that CATID. CanExtend is called and returns the correct per-reference boolean for filtering. However GetExtender is never called so our custom property show and getter/setter never gets hit.

Questions:

  1. Is there a supported way to conditionally show a property on a project reference browse object based on the referenced project's properties/capabilities?

  2. The IExtenderCATIDProvider approach in particular was very promising until we encountered the blocker. Is GetExtender not being called after a successful CanExtend on these project reference nodes expected behavior?

If there is a supported way to achieve conditional per-reference property visibility in the Properties window for a CPS project system, I'd appreciate guidance. If not, please treat this as a feature request for that capability and separately, the CanExtend/GetExtender discrepancy above appears to be a bug.

Thank you and please let me know if any clarification is needed.
Arief Zein

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions