Nested Files in Item Template

2019-08-01 13:53发布

I am trying to create a Visual Studio Item Template that will create a WPF Window with an attached file for a view model

Like the following

VMWindow.xaml ---VMWindow.xaml.cs ---VMWindow.vm.cs

I am able to create the template with the following .vstemplate file

<VSTemplate Type="Item" Version="2.0.0"
    xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
  <TemplateData>
    <Name>Viewmodel Dialog Box</Name>
    <Description>Viewmodel Dialog Box</Description>
    <Icon>Icon.ico</Icon>
    <ProjectType>CSharp</ProjectType>
    <DefaultName>VMDialog</DefaultName>
  </TemplateData>
  <TemplateContent>
    <ProjectItem TargetFileName="$fileinputname$.xaml" SubType="Window">ViewModelDialogTemplate.xaml</ProjectItem>
    <ProjectItem TargetFileName="$fileinputname$.xaml.cs">ViewModelDialogTemplate.xaml.cs</ProjectItem>
    <ProjectItem TargetFileName="$fileinputname$.vm.cs">ViewModelDialogTemplate.vm.cs</ProjectItem>
  </TemplateContent>
</VSTemplate>

I would like for the template to create itself with the .vm.cs file nested inside the main Window file when displayed in Solution Explorer.

I have found the following howto, I am having trouble following it with Visual Studio 2010 though. It was written in 2008, does this still apply?

Code Project article

4条回答
等我变得足够好
2楼-- · 2019-08-01 14:12

You need to implement the Microsoft.VisualStudio.TemplateWizard.IWizard interface, and write a little bit of code to remove the new item from the project and re-add it as the child of another item. Here is a working example from QueryFirst that takes any file with the extension .gen.cs and makes it a child of the same-named .sql file...

    public void ProjectItemFinishedGenerating(ProjectItem
        item)
    {
        string path = item.FileNames[0];
        string parentPath = null;
        if (path.EndsWith(".gen.cs"))
            parentPath = path.Replace(".gen.cs", ".sql");
        if (path.EndsWith("Results.cs"))
            parentPath = path.Replace("Results.cs", ".sql");
        if (!string.IsNullOrEmpty(parentPath))
        {
            ProjectItem parent = item.DTE.Solution.FindProjectItem(parentPath);
            if (parent == null)
                return;
                item.Remove();
                parent.ProjectItems.AddFromFile(path);
        }


    }

To attach the code to the template, you'll need something like this in your .vstemplate file...

<WizardExtension>
    <Assembly>QueryFirst, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4688a60b10e39f04</Assembly>
    <FullClassName>QueryFirst.WizardImplementation</FullClassName>
</WizardExtension>
查看更多
Luminary・发光体
3楼-- · 2019-08-01 14:15

There's a much easier way. You can pull in the same wizard that VS uses to construct composite items. You do this by adding an element at the end of your template, after <TemplateContent>...

<WizardExtension>
    <Assembly>Microsoft.VisualStudio.Web.Application, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</Assembly>
    <FullClassName>Microsoft.VisualStudio.Web.Application.WATemplateWizard</FullClassName>
</WizardExtension>

Then you need to tell the wizard the extension of the parent, and the extension of the children...

<CustomParameters>
  <CustomParameter Name="$ParentExtension$" Value=".xaml"/>
  <CustomParameter Name="$ChildExtension$" Value=".cs"/>
</CustomParameters>

This element goes inside <TemplateContent>.

This solution is tested and working in VS2012, and you can see the version hardcoded in the call to the wizard. If you have version problems, look for the file webform.vstemplate (visual studio's .aspx template), and inspire yourself.

查看更多
相关推荐>>
4楼-- · 2019-08-01 14:20

It's actually very easy...

 <ProjectItem TargetFileName="$fileinputname$.xaml" SubType="Window">ViewModelDialogTemplate.xaml</ProjectItem>
    <ProjectItem TargetFileName="$fileinputname$.xaml/$fileinputname$.xaml.cs">ViewModelDialogTemplate.xaml.cs</ProjectItem>
    <ProjectItem TargetFileName="$fileinputname$.xaml/$fileinputname$.vm.cs">ViewModelDialogTemplate.vm.cs</ProjectItem>
查看更多
我只想做你的唯一
5楼-- · 2019-08-01 14:24

As it turns out the same method works for VS 2010. Required a bit of adaptation but this Code Project article covers the basic idea.

查看更多
登录 后发表回答