ソリューションエクスプローラーフィルターを拡張するExtend the Solution Explorer filter

ソリューションエクスプローラーフィルター機能を拡張して、さまざまなファイルの表示と非表示を切り替えることができます。You can extend Solution Explorer filter functionality to show or hide different files. たとえば、このチュートリアルで示すように、 ソリューションエクスプローラーに C# クラスファクトリファイルのみを表示するフィルターを作成できます。For example, you can create a filter that shows only C# class factory files in the Solution Explorer, as this walkthrough demonstrates.

前提条件Prerequisites

Visual Studio 2015 以降では、ダウンロードセンターから Visual Studio SDK をインストールしません。Starting in Visual Studio 2015, you do not install the Visual Studio SDK from the download center. これは、Visual Studio セットアップでオプション機能として含まれています。It is included as an optional feature in Visual Studio setup. VS SDK は、後でインストールすることもできます。You can also install the VS SDK later on. 詳細については、「 Visual STUDIO SDK のインストール」を参照してください。For more information, see Install the Visual Studio SDK.

Visual Studio パッケージプロジェクトを作成するCreate a Visual Studio package project

  1. という名前の VSIX プロジェクトを作成 FileFilter します。Create a VSIX project named FileFilter. FileFilterという名前のカスタムコマンド項目テンプレートを追加します。Add a custom command item template named FileFilter. 詳細については、「 メニューコマンドを使用して拡張機能を作成する」を参照してください。For more information, see Create an extension with a menu command.

  2. およびへの参照を追加し System.ComponentModel.Composition Microsoft.VisualStudio.Utilities ます。Add a reference to System.ComponentModel.Composition and Microsoft.VisualStudio.Utilities.

  3. メニューコマンドが ソリューションエクスプローラー ツールバーに表示されるようにします。Make the menu command appear on the Solution Explorer toolbar. Filefilterpackage. vsctファイルを開きます。Open the FileFilterPackage.vsct file.

  4. ブロックを <Button> 次のように変更します。Change the <Button> block to the following:

    <Button guid="guidFileFilterPackageCmdSet" id="FileFilterId" priority="0x0400" type="Button">
        <Parent guid="guidSHLMainMenu" id="IDG_VS_TOOLBAR_PROJWIN_FILTERS" />
        <Icon guid="guidImages" id="bmpPic1" />
        <Strings>
            <ButtonText>FileNameFilter</ButtonText>
        </Strings>
    </Button>
    

マニフェスト ファイルを更新するUpdate the manifest file

  1. Source.extension.vsixmanifestファイルで、MEF コンポーネントであるアセットを追加します。In the source.extension.vsixmanifest file, add an asset that is a MEF component.

  2. [ アセット ] タブで、[ 新規 ] ボタンをクリックします。On the Assets tab, choose the New button.

  3. [ 種類 ] フィールドで、[ VisualStudio] を選択します。In the Type field, choose Microsoft.VisualStudio.MefComponent.

  4. [ ソース ] フィールドで、 現在のソリューション内のプロジェクトを選択します。In the Source field, choose A project in current solution.

  5. [ プロジェクト ] フィールドで [ FileFilter] を選択し、[ OK ] をクリックします。In the Project field, choose FileFilter, and then choose the OK button.

フィルターコードを追加するAdd the filter code

  1. いくつかの Guid を FileFilterPackageGuids.cs ファイルに追加します。Add some GUIDs to the FileFilterPackageGuids.cs file:

    public const string guidFileFilterPackageCmdSetString = "00000000-0000-0000-0000-00000000"; // get your GUID from the .vsct file
    public const int FileFilterId = 0x100;
    
  2. FileNameFilter.csという名前の FileFilter プロジェクトにクラスファイルを追加します。Add a class file to the FileFilter project named FileNameFilter.cs.

  3. 空の名前空間と空のクラスを次のコードに置き換えます。Replace the empty namespace and the empty class with the code below.

    メソッドは、 Task<IReadOnlyObservableSet> GetIncludedItemsAsync(IEnumerable<IVsHierarchyItem rootItems) ソリューションのルート () を含むコレクションを取得 rootItems し、フィルターに含める項目のコレクションを返します。The Task<IReadOnlyObservableSet> GetIncludedItemsAsync(IEnumerable<IVsHierarchyItem rootItems) method takes the collection that contains the root of the solution (rootItems) and returns the collection of items to be included in the filter.

    メソッドは、指定した ShouldIncludeInFilter 条件に基づいて、 ソリューションエクスプローラー 階層内の項目をフィルター処理します。The ShouldIncludeInFilter method filters the items in the Solution Explorer hierarchy based on the condition that you specify.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    using Microsoft.Internal.VisualStudio.PlatformUI;
    using Microsoft.VisualStudio.Shell;
    
    namespace FileFilter
    {
        // Implements ISolutionTreeFilterProvider. The SolutionTreeFilterProvider attribute declares it as a MEF component
        [SolutionTreeFilterProvider(FileFilterPackageGuids.guidFileFilterPackageCmdSetString, (uint)(FileFilterPackageGuids.FileFilterId))]
        public sealed class FileNameFilterProvider : HierarchyTreeFilterProvider
        {
            SVsServiceProvider svcProvider;
            IVsHierarchyItemCollectionProvider hierarchyCollectionProvider;
    
            // Constructor required for MEF composition
            [ImportingConstructor]
            public FileNameFilterProvider(SVsServiceProvider serviceProvider, IVsHierarchyItemCollectionProvider hierarchyCollectionProvider)
            {
                this.svcProvider = serviceProvider;
                this.hierarchyCollectionProvider = hierarchyCollectionProvider;
            }
    
            // Returns an instance of Create filter class.
            protected override HierarchyTreeFilter CreateFilter()
            {
                return new FileNameFilter(this.svcProvider, this.hierarchyCollectionProvider, FileNamePattern);
            }
    
            // Regex pattern for CSharp factory classes
            private const string FileNamePattern = @"\w*factory\w*(.cs$)";
    
            // Implementation of file filtering
            private sealed class FileNameFilter : HierarchyTreeFilter
            {
                private readonly Regex regexp;
                private readonly IServiceProvider svcProvider;
                private readonly IVsHierarchyItemCollectionProvider hierarchyCollectionProvider;
    
                public FileNameFilter(
                    IServiceProvider serviceProvider,
                    IVsHierarchyItemCollectionProvider hierarchyCollectionProvider,
                    string fileNamePattern)
                {
                    this.svcProvider = serviceProvider;
                    this.hierarchyCollectionProvider = hierarchyCollectionProvider;
                    this.regexp = new Regex(fileNamePattern, RegexOptions.IgnoreCase);
                }
    
                // Gets the items to be included from this filter provider.
                // rootItems is a collection that contains the root of your solution
                // Returns a collection of items to be included as part of the filter
                protected override async Task<IReadOnlyObservableSet> GetIncludedItemsAsync(IEnumerable<IVsHierarchyItem> rootItems)
                {
                    IVsHierarchyItem root = HierarchyUtilities.FindCommonAncestor(rootItems);
                    IReadOnlyObservableSet<IVsHierarchyItem> sourceItems;
                    sourceItems = await hierarchyCollectionProvider.GetDescendantsAsync(
                                        root.HierarchyIdentity.NestedHierarchy,
                                        CancellationToken);
    
                    IFilteredHierarchyItemSet includedItems = await hierarchyCollectionProvider.GetFilteredHierarchyItemsAsync(
                        sourceItems,
                        ShouldIncludeInFilter,
                        CancellationToken);
                    return includedItems;
                }
    
                // Returns true if filters hierarchy item name for given filter; otherwise, false</returns>
                private bool ShouldIncludeInFilter(IVsHierarchyItem hierarchyItem)
                {
                    if (hierarchyItem == null)
                    {
                        return false;
                    }
                    return this.regexp.IsMatch(hierarchyItem.Text);
                }
            }
        }
    }
    
    
  4. FileFilter.csで、FileFilter コンストラクターからコマンド配置および処理コードを削除します。In FileFilter.cs, remove the command placement and handling code from the FileFilter constructor. 結果は次のようになります。The result should look like this:

    private FileFilter(Package package)
    {
        if (package == null)
        {
            throw new ArgumentNullException("package");
        }
    
        this.package = package;
    }
    

    ShowMessageBox()メソッドも削除します。Remove the ShowMessageBox() method as well.

  5. FileFilterPackage.csで、メソッド内のコードを Initialize() 次のコードに置き換えます。In FileFilterPackage.cs, replace the code in the Initialize() method with the following:

    protected override void Initialize()
    {
        Debug.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
        base.Initialize();
    }
    

コードのテストTest your code

  1. プロジェクトをビルドして実行します。Build and run the project. Visual Studio の 2 番目のインスタンスが表示されます。A second instance of Visual Studio appears. これは実験用インスタンスと呼ばれます。This is called the experimental instance.

  2. Visual Studio の実験用インスタンスで、C# プロジェクトを開きます。In the experimental instance of Visual Studio, open a C# project.

  3. ソリューションエクスプローラーツールバーで追加したボタンを探します。Look for the button you added on the Solution Explorer toolbar. 左側の4番目のボタンになります。It should be the fourth button from the left.

  4. このボタンをクリックすると、すべてのファイルが除外され、すべての項目がビューからフィルター処理されていることがわかります。When you click the button, all the files should be filtered out, and you should see All items have been filtered from view. ソリューションエクスプローラーにあります。in the Solution Explorer.