次の方法で共有


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

ソリューション エクスプローラーのフィルター機能を拡張して、異なるファイルの表示と非表示を切り替えることができます。 たとえば、このチュートリアルで示すように、 ソリューション エクスプローラーで C# クラス ファクトリ ファイルのみを表示するフィルターを作成できます。

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

  1. FileFilterという名前の VSIX プロジェクトを作成します。 FileFilter という名前のカスタム コマンド項目テンプレートを追加します。 詳細については、「 メニュー コマンドを使用して拡張機能を作成する」を参照してください。

  2. System.ComponentModel.CompositionMicrosoft.VisualStudio.Utilitiesへの参照を追加します。

  3. ソリューション エクスプローラーのツール バーにメニュー コマンドを表示します。 FileFilterPackage.vsct ファイルを開きます。

  4. <Button> ブロックを次のように変更します。

    <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>
    

マニフェスト ファイルを更新する

  1. source.extension.vsixmanifest ファイルに、MEF コンポーネントである資産を追加します。

  2. [アセット] タブ 、[ 新規 ] ボタンを選択します。

  3. [ 種類 ] フィールドで、 Microsoft.VisualStudio.MefComponent を選択します。

  4. [ ソース ] フィールドで、 現在のソリューションのプロジェクトを選択します。

  5. [ プロジェクト ] フィールドで [ FileFilter] を選択し、[ OK] ボタンをクリックします。

フィルター コードを追加する

  1. FileFilterPackageGuids.cs ファイルにいくつかの GUID を追加します。

    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 プロジェクトにクラス ファイル 追加します。

  3. 空の名前空間と空のクラスを次のコードに置き換えます。

    Task<IReadOnlyObservableSet> GetIncludedItemsAsync(IEnumerable<IVsHierarchyItem rootItems) メソッドは、ソリューションのルート (rootItems) を含むコレクションを取得し、フィルターに含める項目のコレクションを返します。

    ShouldIncludeInFilter メソッドは、指定した条件に基づいてソリューション エクスプローラー階層の項目をフィルター処理します。

    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 コンストラクターからコマンドの配置と処理コードを削除します。 結果は次のようになります。

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

    ShowMessageBox() メソッドも削除します。

  5. FileFilterPackage.csで、Initialize() メソッドのコードを次のように置き換えます。

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

コードをテストする

  1. プロジェクトをビルドして実行します。 Visual Studio の 2 番目のインスタンスが表示されます。 これは実験用インスタンスと呼ばれます。

  2. Visual Studio の実験用インスタンスで、C# プロジェクトを開きます。

  3. ソリューション エクスプローラーのツール バーに追加したボタンを探します。 左側の 4 番目のボタンである必要があります。

  4. ボタンをクリックすると、すべてのファイルがフィルター処理され、 すべての項目がビューからフィルター処理されている ことがわかります。 ソリューション エクスプローラーで確認できます。