How to find and implement an event which gets called on Expand of nodes (project or folder) in Solution Explorer ??

Shriram Kardile 0 Reputation points
2023-10-09T09:22:31.1666667+00:00

Hello Visual Studio Extension Experts,

  1. I am struggling to get the event, which gets called when a user Expands any node (project or folder) in Solution Explorer in Visual Studio. (I want to implement a logic to get latest status of file from source repo on the expand click of a user.)
  2. Also, I am trying to find the visibility of the files while opening any solution in visual studio. Some files may be already visible. And some files might be hidden due to folder/project is not expanded. (So status of only visible files can be fetched from the source repo.)

It would be really helpful for me if the above 2 things are resolved for me. It will help me in implementing source control manager extension.

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,603 questions
Visual Studio Extensions
Visual Studio Extensions
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Extensions: A program or program module that adds functionality to or extends the effectiveness of a program.
191 questions
{count} votes

1 answer

Sort by: Most helpful
  1. gekka 8,061 Reputation points MVP
    2023-10-11T11:45:17.79+00:00

    I tried to use IVsHierarchy.AdviseHierarchyEvents with VSHPROPID_Expanded to IVsSolution , but the event is not fire.

    So next, I tried registering event detect from tree control.

    // PresentationCore
    // PresentationFramework
    // System.Xaml
    // WindowsBase
    
    using System;
    using System.Runtime.InteropServices;
    using System.Threading;
    using Microsoft.VisualStudio.Shell;
    using Microsoft.VisualStudio.Shell.Interop;
    using System.Collections.Generic;
    using System.Linq;
    using static Microsoft.VisualStudio.ErrorHandler;
    
    namespace Gekka.VisualStudio.SolutionExploreExpandHackPackage
    {
        [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
        [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids.NoSolution, PackageAutoLoadFlags.BackgroundLoad)]
        [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids.EmptySolution, PackageAutoLoadFlags.BackgroundLoad)]
        [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids.SolutionExists, PackageAutoLoadFlags.BackgroundLoad)]
        [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids.SolutionHasSingleProject, PackageAutoLoadFlags.BackgroundLoad)]
        [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids.SolutionHasMultipleProjects, PackageAutoLoadFlags.BackgroundLoad)]
        [Guid(SolutionExploreExpandHackPackage.PackageGuidString)]
        public sealed class SolutionExploreExpandHackPackage : AsyncPackage
        {
            public const string PackageGuidString = "026bc0c8-e89a-412e-aae1-66a5f34f7727";
    
            protected override async System.Threading.Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
            {
                await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
    
                System.Windows.EventManager.RegisterClassHandler
                    (typeof(Microsoft.Internal.VisualStudio.PlatformUI.PivotTreeView)
                    , Microsoft.Internal.VisualStudio.PlatformUI.PivotTreeView.PreviewMouseDownEvent
                    , new System.Windows.RoutedEventHandler((s, e) =>
                    {
                        if (s.GetType().Name.Contains("SolutionPivotTreeView"))
                        {
                            var ptv = (Microsoft.Internal.VisualStudio.PlatformUI.PivotTreeView)s;
                            ptv.NodeExpanded -= treeView_NodeExpanded;
                            ptv.NodeExpanded += treeView_NodeExpanded;
                        }
                    }), true);
            }
    
            private void treeView_NodeExpanded(object sender, Microsoft.Internal.VisualStudio.PlatformUI.TreeNodeEventArgs e)
            {
                if (e.Node != null)
                {
                     Dump(e.Node, 0);
                }           
            }
    
            private static void Dump(Microsoft.Internal.VisualStudio.PlatformUI.IVirtualizingTreeNode node, int lv)
            {
                  ThreadHelper.ThrowIfNotOnUIThread();
                if (node.Item is Microsoft.VisualStudio.Shell.IAttachedCollectionSource cs)
                {
                    if (cs.SourceItem is Microsoft.VisualStudio.Shell.IVsHierarchyItem hitem)
                    {
                        IVsHierarchyItemIdentity hii = hitem.HierarchyIdentity;
    
                        Succeeded(hii.Hierarchy.GetProperty(hii.ItemID, (int)__VSHPROPID.VSHPROPID_Name, out var name));
                        Succeeded(hii.Hierarchy.GetProperty(hii.ItemID, (int)__VSHPROPID.VSHPROPID_Caption, out var caption));
                        Succeeded(hii.Hierarchy.GetProperty(hii.ItemID, (int)__VSHPROPID2.VSHPROPID_IsLinkFile, out var isLink));
                        
                        System.Diagnostics.Debug.WriteLine($"{new string(' ', lv)}└ {caption}\t{name}\t{isLink}");
    
                    }
                }
                foreach (Microsoft.Internal.VisualStudio.PlatformUI.IVirtualizingTreeNode childNode in node.ChildNodes)
                {
                    Dump(childNode, lv + 1);
                }
            }
        }
    
    }
    

    Solution Explore can be displayed in multiple views, this code can detect expand the nodes in each view.

    0 comments No comments