我正在为Visual Studio 2015编写一个小扩展。 我添加了一个VSPackage,以便在右键单击解决方案资源管理器中的项目或文件夹时,在快捷菜单上嵌入一些CustomCommands。
我现在要做的是“打开添加新项对话框,然后选择我使用此VSPackage安装的模板之一”。
这是我用来初始化命令的代码:
private TemplateCommand(Package package)
{
if (package == null)
throw new ArgumentNullException(nameof(package));
_package = package;
var commandService = ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (commandService == null)
return;
AddCommand(commandService, CommandId, CreateCustomTemplate);
}
CreateCustomTemplate回调代码是这样的:(目前我只是创建一个messageBox,只是为了确保它有效)
private void CreateCustomTemplate(object sender, EventArgs eventArgs)
{
//TODO: code to replace!
var message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.CreateCustomTemplate()", GetType().FullName);
// Show a message box to prove we were here
VsShellUtilities.ShowMessageBox(
ServiceProvider,
message,
"CREATE CustomTemplate",
OLEMSGICON.OLEMSGICON_INFO,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
}
那么,回顾一下,如何打开“添加新项目”对话框并选择特定项目模板?
例如,当您尝试创建一个Class或UserControl时右键单击解决方案资源管理器中的文件夹
这正是我想要实现的目标。显然我想创建自己的模板,而不是UserControl。
如果您需要任何澄清,请随时提出。 提前感谢您的任何建议
答案 0 :(得分:0)
您可以执行命令“Project.AddNewItem”或“File.AddNewItem”来显示对话框。有几种以编程方式执行命令的方法,最简单的方法是获取EnvDTE.DTE实例并调用dte.ExecuteCommand(commandName)。
关于选择所需模板,请参阅parameters for the command File.AddNewItem。幸运的是,Project.AddNewItem命令是相同的。
答案 1 :(得分:0)
最后我解决了我的问题。
不幸的是,命令File.AddNewItem(或Project.AddNewItem)不适合我的情况,因为我想看到AddNewFile对话框(这些命令只是将项目添加到指定的项目中)。
我找到了解决网络问题的解决方案here,特别感谢Vladimir.Ilic的答案。
这是我用来实现目标的代码:
internal sealed class TemplateCommand
{
private const int CustomCommandId = 0x1023;
private static readonly Guid CommandSet = COMMANDSET_GUID;
private readonly Package _package;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
public IServiceProvider ServiceProvider => _package;
public static TemplateCommand Instance { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
// ReSharper restore MemberCanBePrivate.Global
public static void Initialize(Package package)
{
Instance = new TemplateCommand(package);
}
private TemplateCommand(Package package)
{
if (package == null)
throw new ArgumentNullException(nameof(package));
_package = package;
var commandService = ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (commandService == null)
return;
AddCommand(commandService, CustomCommandId, CreateCustomCommand);
}
private static void AddCommand(IMenuCommandService commandService, int commandId, EventHandler callback)
{
var command = new CommandID(CommandSet, commandId);
var menuItem = new MenuCommand(callback, command);
commandService.AddCommand(menuItem);
}
private void CreateCustomCommand(object sender, EventArgs eventArgs)
{
AddNewItem("MyCustomCommand");
}
private void AddNewItem(string itemName)
{
var dte = ServiceProvider.GetService(typeof(DTE)) as DTE;
if (dte == null)
return;
int iDontShowAgain;
uint projectItemId;
var strFilter = string.Empty;
var hierarchy = GetCurrentVsHierarchySelection(out projectItemId);
if (hierarchy == null)
return;
var project = ToDteProject(hierarchy);
if (project == null)
return;
var vsProject = ToVsProject(project);
if (vsProject == null)
return;
var addItemDialog = ServiceProvider.GetService(typeof(IVsAddProjectItemDlg)) as IVsAddProjectItemDlg;
if (addItemDialog == null)
return;
const uint uiFlags = (uint)(__VSADDITEMFLAGS.VSADDITEM_AddNewItems | __VSADDITEMFLAGS.VSADDITEM_SuggestTemplateName | __VSADDITEMFLAGS.VSADDITEM_AllowHiddenTreeView);
const string categoryNameInNewFileDialog = "MyCustomTemplates";
// ProjectGuid for C# projects
var projGuid = new Guid("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC");
string projectDirectoryPath;
hierarchy.GetCanonicalName(projectItemId, out projectDirectoryPath);
var itemNameInNewFileDialog = itemName;
addItemDialog.AddProjectItemDlg(projectItemId,
ref projGuid,
vsProject,
uiFlags,
categoryNameInNewFileDialog,
itemNameInNewFileDialog,
ref projectDirectoryPath,
ref strFilter,
out iDontShowAgain);
}
private static IVsHierarchy GetCurrentVsHierarchySelection(out uint projectItemId)
{
IntPtr hierarchyPtr, selectionContainerPtr;
IVsMultiItemSelect mis;
var monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection));
monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);
var hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;
return hierarchy;
}
private static Project ToDteProject(IVsHierarchy hierarchy)
{
if (hierarchy == null)
throw new ArgumentNullException(nameof(hierarchy));
object prjObject;
if (hierarchy.GetProperty(0xfffffffe, (int)__VSHPROPID.VSHPROPID_ExtObject, out prjObject) == VSConstants.S_OK)
return (Project)prjObject;
throw new ArgumentException("Hierarchy is not a project.");
}
private IVsProject ToVsProject(Project project)
{
if (project == null)
throw new ArgumentNullException(nameof(project));
var vsSln = ServiceProvider.GetService(typeof(IVsSolution)) as IVsSolution;
if (vsSln == null)
throw new ArgumentException("Project is not a VS project.");
IVsHierarchy vsHierarchy;
vsSln.GetProjectOfUniqueName(project.UniqueName, out vsHierarchy);
// ReSharper disable SuspiciousTypeConversion.Global
var vsProject = vsHierarchy as IVsProject;
// ReSharper restore SuspiciousTypeConversion.Global
if (vsProject != null)
return vsProject;
throw new ArgumentException("Project is not a VS project.");
}
}
非常感谢那些经过尝试(或者甚至想过)帮助的人!
希望这有助于某人,
此致