15.1 创建模板

模板有两类:创建新项目项的模板和创建整个项目的模板。这两种模板有相同的结构(后面可以看到该结构),但放在不同的模板文件夹中。项目模板位于New Project对话框中,而项模板位于Add New Item对话框中。

15.1.1 项模板

可以手动构建模板,也可以从现有的项目项中创建模板,再根据需要修改它,这种方法更快。本节首先介绍项模板,这里以About窗体为例,它包含某些基本信息,如应用程序的版本号和作者。

首先使用自己选择的语言创建一个Windows Forms应用程序StarterProject。可以定制Visual Studio附带的About Box模板,而不是从头开始创建About窗体。右击StarterProject项目,选择Add | New Item命令,并添加一个新的About Box(命名为AboutForm)。通过删除徽标和TableLayoutPanel控件的第一列(选择表布局面板,进入Properties窗口,选择Columns属性,单击其省略号按钮,再删除列1),定制默认的About窗体。定制好的About窗体如图15-1所示。

图15-1

为通过About窗体创建一个模板,可从File菜单中选择Export Template项。这会启动Export Template向导,如图15-2所示。如果在解决方案中有未保存的修改,则向导将会提示保存这些修改。第一步是确定要创建什么类型的模板。这里选择Item Template单选按钮,确保在下拉列表中选择了About窗体所在的项目。

图15-2

单击Next按钮,向导将提示选择模板所基于的项。这里选择About窗体。对话框中的复选框有点误导作用,因为模板只能基于一个项(选择第二项会取消选择已选择的项)。之后单击Next按钮,打开如图15-3所示的对话框,该对话框可以指定包含需要的任意程序集引用。这个列表基于项所在项目中的引用列表。由于这是一个窗体,因此包含对System.Windows.Forms库的引用。添加这个类型的新项时,会在项目中自动添加该引用(如果还没有添加的话)。否则,如果没有对这个程序集的引用,项目就可能未编译(Class Library项目默认不引用这个程序集)。

图15-3

选择一个程序集后,列表的下方可能会显示一个警告,说明所选的程序集没有随Visual Studio一起安装。如果程序集在用户的计算机上不可用,则用户就不能使用该模板。要注意这个问题,并且仅选择项需要的程序集。

Export Template向导的最后一步是指定要生成的模板的一些属性,如显示在Add New Item对话框中的名称、描述以及图标。

图15-4显示了向导中的最后一个对话框。它包含两个复选框,一个用于显示完成时的输出文件夹,另一个用于在Visual Studio 2015中自动导入新模板。

图15-4

默认情况下,导出的模板在当前用户的Documents/Visual Studio 2015文件夹的My Exported Templates文件夹下创建。在这个根文件夹中有许多文件夹,包含了用户的Visual Studio 2015设置,如图15-5所示。

图15-5

还要注意图15-5中的Templates文件夹,Visual Studio 2015在这个文件夹中查找创建新项时显示的其他模板。在Templates文件夹下有两个子文件夹,它们分别包含项模板和项目模板。这些文件夹还按编程语言进一步细分。如果选择Export Template向导最后一个页面上的Automatically import the template into Visual Studio选项,那么新模板将不仅位于输出文件夹中,还会根据编程语言和模板类型复制到Templates文件夹中相关的位置上。Visual Studio 2015下次显示Add New Item对话框时,会自动显示这个项模板,如图15-6所示。

图15-6

如果希望某个项模板或项目模板出现在Add New Item/New Project对话框中现有的类别(或自己的类别)下(如Windows Forms类别),那么只需要创建一个文件夹,用类别名给该文件夹命名,把模板放在其中即可(在相关的位置下)。下次打开Add New Item/New Project对话框时,模板就会显示在与文件夹名对应的类别下(如果没有匹配文件夹名的类别,则模板就显示在新类别下)。

15.1.2 项目模板

构建项目模板的方式与构建项模板相同,但有一个区别。项模板基于已有的项,而项目模板需要基于整个项目。例如,一个简单的项目ProjectTemplateExample如图15-7所示,它有主窗体、About窗体以及初始屏幕。

图15-7

要从这个项目中生成一个模板,所执行的步骤与生成项模板相同,但在指定要生成的模板类型时,应该选择Project Template,并且没有选择项目模板所包含的项的步骤(项目中的所有项都包含在模板中)。完成了Export Template向导后,新的项目模板就出现在New Project对话框中,如图15-8所示。

图15-8

15.1.3 模板结构

在介绍如何构建更复杂的模板之前,需要先理解Export Template向导产生的内容。在My Exported Templates文件夹中,所有模板都导出为一个压缩的zip文件。zip文件包含了各种不同类型的文件和文件夹,具体的内容取决于它是单一文件的模板还是整个项目的模板。但是,每个模板zip文件都包含一个.vstemplate文件,这是一个包含模板配置的XML文档。下面的.vstemplate文件作为前面项目模板的一部分导出。

      <VSTemplate Version="3.0.0"
          xmlns="http://schemas.microsoft.com/developer/vstemplate/2005"
      Type="Project">
        <TemplateData>
          <Name>ProjectTemplateExample</Name>
          <Description>Project Template Example</Description>
          <ProjectType>VisualBasic</ProjectType>
          <ProjectSubType>
          </ProjectSubType>
          <SortOrder>1000</SortOrder>
          <CreateNewFolder>true</CreateNewFolder>
          <DefaultName>ProjectTemplateExample</DefaultName>
          <ProvideDefaultName>true</ProvideDefaultName>
          <LocationField>Enabled</LocationField>
          <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
          <Icon>__TemplateIcon.ico</Icon>
        </TemplateData>
        <TemplateContent>
          <Project TargetFileName="ProjectTemplateExample.vbproj"
      File="ProjectTemplateExample.vbproj" ReplaceParameters="true">
            <ProjectItem ReplaceParameters="true" TargetFileName="AboutForm.vb">
      AboutForm.vb</ProjectItem>
            <ProjectItem ReplaceParameters="true" TargetFileName="AboutForm.Designer.vb">
      AboutForm.Designer.vb</ProjectItem>
            <ProjectItem ReplaceParameters="true" TargetFileName="AboutForm.resx">
      AboutForm.resx</ProjectItem>
            <ProjectItem ReplaceParameters="true" TargetFileName="App.config">
      App.config</ProjectItem>
            <ProjectItem ReplaceParameters="true" TargetFileName="MainForm.vb">
      MainForm.vb</ProjectItem>
            <ProjectItem ReplaceParameters="true" TargetFileName="MainForm.Designer.vb">
      MainForm.Designer.vb</ProjectItem>
            <Folder Name="My Project" TargetFolderName="My Project">
              <ProjectItem ReplaceParameters="true" TargetFileName="Application.myapp">
      Application.myapp</ProjectItem>
              <ProjectItem ReplaceParameters="true" TargetFileName="Application.Designer.vb">
      Application.Designer.vb</ProjectItem>
              <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.vb">
      AssemblyInfo.vb</ProjectItem>
              <ProjectItem ReplaceParameters="true" TargetFileName="Resources.resx">
      Resources.resx</ProjectItem>
              <ProjectItem ReplaceParameters="true" TargetFileName="Resources.Designer.vb">
      Resources.Designer.vb</ProjectItem>
              <ProjectItem ReplaceParameters="true" TargetFileName="Settings.settings">
      Settings.settings</ProjectItem>
              <ProjectItem ReplaceParameters="true" TargetFileName="Settings.Designer.vb">
      Settings.Designer.vb</ProjectItem>
            </Folder>
            <ProjectItem ReplaceParameters="true" TargetFileName="SplashForm.vb">
      SplashForm.vb</ProjectItem>
            <ProjectItem ReplaceParameters="true" TargetFileName="SplashForm.Designer.vb">
      SplashForm.Designer.vb</ProjectItem>
            <ProjectItem ReplaceParameters="true" TargetFileName="SplashForm.resx">
      SplashForm.resx</ProjectItem>
          </Project>
        </TemplateContent>
      </VSTemplate>

在该文件顶部,VSTemplate节点包含了一个Type特性,它确定这是一个项模板(Item)、项目模板(Project)还是多项目模板(ProjectGroup)。该文件的其余部分分为TemplateData和TemplateContent。TemplateData块包含模板本身的信息,如名称、描述以及在New Project对话框中表示该模板的图标;而TemplateContent块定义了模板的文件结构。

在前面的例子中,内容以一个Project节点为开头,它表示要使用的项目文件。包含在这个模板中的文件用ProjectItem节点的方式列出。每个节点都包含一个TargetFileName特性来指定文件名,因为它将显示在通过这个模板创建的项目中。对于项模板,没有Project节点,ProjectItem包含在TemplateContent节点中。

可为包含多个项目的解决方案创建模板。这些模板为解决方案中的每个项目包含一个.vstemplate文件。它们还有一个全局.vstemplate文件,该文件描述了整个模板,包含了每个项目的.vstemplate文件引用。但创建这个文件需要手动进行,因为Visual Studio当前没有导出解决方案模板的功能。

关于.vstemplate文件结构的更多信息,可以参见%programfiles%\Microsoft Visual Studio 14.0\Xml\ Schemas\1033\vstemplate.xsd下的完整模式。

15.1.4 模板参数

项模板和项目模板都支持参数替代,即从模板中创建项目或项时,允许替代关键参数。在一些情况下,这些参数是自动插入的。例如,当把About窗体作为一个项模板导出时,会删除类名,并以一个模板参数代替,如下所示:

      Public Class $safeitemname$

在任意项目中,都可以使用如下14个保留模板参数,如表15-1所示。

表15-1 模板参数

除了保留的参数外,还可以创建定制的模板参数。为此,需要在.vstemplate文件中添加一个<CustomParameters>部分,如下所示:

      <TemplateContent>
          ...
          <CustomParameters>
              <CustomParameter Name="$timezoneName $" Value="(GMT+8:00) Perth"/>
              <CustomParameter Name="$timezoneOffset $" Value="+8"/>
          </CustomParameters>
      </TemplateContent>

在代码中引用这个定制参数的方式如下:

      string tzName = "$timezoneName$";
      string tzOffset = "$timezoneOffset$";

从模板中创建包含定制参数的新项或项目时,Visual Studio会自动给定制参数和保留参数执行模板替代。

15.1.5 模板位置

默认情况下,定制的项模板和项目模板存储在用户个人的Documents\Visual Studio 2015\ Templates文件夹下,但可以通过Options对话框把它重定向到另一个位置(例如,网络上的一个共享目录,以便与同事使用相同的定制模板)。进入Tools | Options,选择Projects and Solutions节点,接着为定制模板选择另一个位置即可。