Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a VS 2017 custom project system, how can I make a project item bold in the Solution Explorer?

I'm writing a project system extension for VS 2017, and each project in my language has one file that's the "startup file". I want that file to appear bold in the Solution Explorer.

Python Tools for VS does what I'm looking for, but my extension is built on the new project system framework (CPS). The CPS way to change the appearance of Solution Explorer items is to implement IProjectTreePropertiesProvider, but I don't see any way to change the text style with it -- only the icons.

like image 510
Jesse McGrew Avatar asked Jul 26 '17 12:07

Jesse McGrew


People also ask

What is the difference between a project and a solution in Visual Studio?

A project is contained within a solution. Despite its name, a solution isn't an "answer". It's simply a container for one or more related projects, along with build information, Visual Studio window settings, and any miscellaneous files that aren't associated with a particular project.

Where is project settings in Visual Studio?

You access project properties by right-clicking the project node in Solution Explorer and choosing Properties, or by typing properties into the search box on the menu bar and choosing Properties Window from the results. . NET projects might also have a properties node in the project tree itself.

How do I use Solution Explorer in Visual Studio?

By default, the Solution Explorer tool window appears as a pane in the upper-right side of the Visual Studio integrated development environment (IDE). If you don't see the Solution Explorer tool window, you can open it from the Visual Studio menu bar by using View > Solution Explorer, or by pressing Ctrl+Alt+L.


1 Answers

I'm not sure CPS has anything builtin for this, but you still can use the mix of "old" native/managed Visual Studio interfaces. This is an example that uses IProjectTreePropertiesProvider:

[Export(typeof(IProjectTreePropertiesProvider))]
[AppliesTo(MyUnconfiguredProject.UniqueCapability)]
[Order(1000)]
internal class ProjectTreePropertiesProvider1 : IProjectTreePropertiesProvider
{
    // we need to import that to do COM calls
    [Import]
    protected IProjectThreadingService ThreadingService { get; set; }

    // we want the "old" IVsHierarchy interface 
    [ImportMany(ExportContractNames.VsTypes.IVsHierarchy)]
    private OrderPrecedenceImportCollection<IVsHierarchy> IVsHierarchies { get; }
    private IVsHierarchy VsHierarchy => IVsHierarchies.First().Value;

    [ImportingConstructor]
    public ProjectTreePropertiesProvider1(UnconfiguredProject unconfiguredProject)
    {
        IVsHierarchies = new OrderPrecedenceImportCollection<IVsHierarchy>(projectCapabilityCheckProvider: unconfiguredProject);
    }

    /// <summary>
    /// Calculates new property values for each node in the project tree.
    /// </summary>
    /// <param name="propertyContext">Context information that can be used for the calculation.</param>
    /// <param name="propertyValues">Values calculated so far for the current node by lower priority tree properties providers.</param>
    public async void CalculatePropertyValues(IProjectTreeCustomizablePropertyContext propertyContext, IProjectTreeCustomizablePropertyValues propertyValues)
    {
        // this is from the standard WindowsScript project type sample
        if (propertyValues.Flags.Contains(ProjectTreeFlags.Common.ProjectRoot))
        {
            // etc..
            propertyValues.Icon = KnownMonikers.JSProjectNode.ToProjectSystemType();
            // etc..
        }

        // now, we're doing some COM calls, ensure it happens on UI thread
        await ThreadingService.SwitchToUIThread();

        // get the id of some item (this "Start.js" item is from the standard sample)
        VsHierarchy.ParseCanonicalName("Start.js", out uint id);

        // get IVsUIShell from service provider
        VsHierarchy.GetSite(out Microsoft.VisualStudio.OLE.Interop.IServiceProvider sp);
        var shell = (IVsUIShell)sp.QueryService<IVsUIShell>();

        // get solution explorer's window
        var SolutionExplorer = new Guid(ToolWindowGuids80.SolutionExplorer);
        shell.FindToolWindow(0, ref SolutionExplorer, out IVsWindowFrame frame);

        // get solution explorer's DocView
        frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocView, out object obj);
        var window = (IVsUIHierarchyWindow2)obj;

        // change attribute of the item
        window.SetItemAttribute((IVsUIHierarchy)VsHierarchy, id, (uint)__VSHIERITEMATTRIBUTE.VSHIERITEMATTRIBUTE_Bold, true);
    }
}
like image 182
Simon Mourier Avatar answered Sep 24 '22 15:09

Simon Mourier