トップ回答者
ソリューション・エクスプローラのツリービューへの振り分けを、ファイルの拡張子ではなくファイル名を条件にしたい

質問
回答
-
フィルタの下層にさらにフィルタを作れるので、その頭文字毎のフィルタを作って振り分けで代用してもいいなら。
頭文字による自動振り分けを拡張機能で書いてみた
using System; using System.Runtime.InteropServices; using System.ComponentModel.Design; using Microsoft.VisualStudio.Shell; using System.Collections; using System.Collections.Generic; using System.Linq; using Microsoft.VisualStudio.VCProjectEngine; namespace Company.CPPFilterTest { [PackageRegistration(UseManagedResourcesOnly = true)] [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] [ProvideMenuResource("Menus.ctmenu", 1)] [Guid(GuidList.guidCPPFilterTestPkgString)] [ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids80.SolutionExists)] public sealed class CPPFilterTestPackage : Package { private EnvDTE.DTE _DTE; private EnvDTE.SolutionEvents _SolutionEvents; private VCProjectEngineEvents _VCProjectEvents; protected override void Initialize() { base.Initialize(); OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (null != mcs) { CommandID menuCommandID = new CommandID(GuidList.guidCPPFilterTestCmdSet, (int)PkgCmdIDList.CppFilterTest); MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID); mcs.AddCommand(menuItem); } _DTE = (EnvDTE.DTE)GetService(typeof(EnvDTE.DTE)); _SolutionEvents = _DTE.Events.SolutionEvents; _SolutionEvents.Opened += _SolutionEvents_Opened; } void _SolutionEvents_Opened() { if (_VCProjectEvents == null) { foreach (dynamic o in _DTE.Solution.Projects) { if (o.Kind == "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") { VCProject proj = o.Object as VCProject; VCProjectEngine engine = proj.VCProjectEngine as VCProjectEngine; _VCProjectEvents = engine.Events as VCProjectEngineEvents; _VCProjectEvents.ItemAdded += _VCProjectEvents_ItemAdded; _VCProjectEvents.ItemRenamed += _VCProjectEvents_ItemRenamed; break; } } } } /// <summary>新しくファイルを追加した</summary> void _VCProjectEvents_ItemAdded(object Item, object ItemParent) { VCFilter parentFilter = ItemParent as VCFilter; VCFile file = Item as VCFile; Move(file, parentFilter); } /// <summary>ファイル名を変更した</summary> void _VCProjectEvents_ItemRenamed(object Item, object ItemParent, string OldName) { VCFilter parentFilter = ItemParent as VCFilter; VCFile file = Item as VCFile; Move(file, parentFilter); } /// <summary>ファイル名に合わせて名前別のフィルタへ移動</summary> private void Move(VCFile file, VCFilter parentFilter) { if (file != null && parentFilter != null) { var nameParts = parentFilter.CanonicalName.Split('\\'); var proj = file.project as VCProject; foreach (VCFilter rootFilter in ((dynamic)proj.Filters)) { if (rootFilter.Name == nameParts[0]) { string filterName = file.Name[0].ToString().ToUpper(); foreach (VCFilter childFilter in ((dynamic)rootFilter.Filters)) { if (childFilter.Name == filterName) { if (file.CanMove(childFilter)) { file.Move(childFilter); } return; } } { VCFilter childFilter = (VCFilter)rootFilter.AddFilter(filterName); if (file.CanMove(childFilter)) { file.Move(childFilter); } } } } } } /// <summary>既存のファイルを新しいフィルタ(仮想フォルダの代用)に振り分ける</summary> private void MenuItemCallback(object sender, EventArgs e) { foreach (dynamic d in _DTE.Solution.Projects) { dynamic proj = d.Object; foreach (VCFilter parentFilter in proj.Filters) { if (parentFilter.CanonicalName.Contains('\\')) { continue; } Dictionary<char, VCFilter> dic = new Dictionary<char, VCFilter>(); foreach (VCFilter childFilter in ((dynamic)parentFilter.Filters)) { if (childFilter.Name.Length == 1) { dic.Add(childFilter.Name[0], childFilter); } } for (int i = (int)'A'; i <= (int)'Z'; i++) { char c = (char)i; VCFilter childFilter; if (dic.ContainsKey(c)) { childFilter = dic[c]; } else { childFilter = (VCFilter)parentFilter.AddFilter(c.ToString()); dic.Add(c, childFilter); } var items = ((IEnumerable)parentFilter.Items) .Cast<dynamic>() .Where(_ => _.Name.ToString().ToUpper().StartsWith(c.ToString())) .ToArray(); foreach (VCFile file in items) { var name = file.Name.ToString(); if (file.CanMove(childFilter)) { file.Move(childFilter); } } if (((dynamic)childFilter.Items).Count == 0) { childFilter.Remove(); } } } } } } }
*.filtersはXMLファイルなので、即時反映でなくてもいいならXMLファイル編集で振り分けでも可能ですね
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク 星 睦美 2016年4月20日 6:42