Custom Visual Studio Context Menus - visual-studio

I want to use T4 templates to automatically create some code but I want to add a user input box (to ask for a name, for example) similar to the MVC3 "Add View" / "Add Controller" dialog when you right click on a specific folder. Is this possible with pure T4 templates or is it going to result in a writing a VS plugin DLL? If it involves writing a DLL can I just plop that into the projects reference and use it per-project or does it have to be registered individually on each machine?

Managed to figure it out. I probably should of tried this first. Just add the required imports to your T4 template:
<## assembly name="System.Windows.Forms.dll" #>
<## assembly name="System.Drawing.dll" #>
<## import namespace="System.Windows.Forms" #>
<## import namespace="System.Drawing" #>
and then create a form programmatically with a label, input box and button. On DialogResult.OK (for example) just read the input value and do what you need with it. Works perfectly :-)

Related

Add template file without custom tool to project programmatically

We add a structure of T4 template files (tt and ttinclude ones) in a project in Visual Studio.
For these templates we are using our custom transformation and processing and we do NOT want the Custom Tool setting of the tt files which by default is set to TextTemplatingFileGenerator.
In order to achieve that we are using the following code:
... // logic for the files creation
ProjectItem addedItem = this.project.ProjectItems.AddFromFile(fileFullPath);
addedItem.Properties.Item("CustomTool").Value = string.Empty;
The problem is that when the files are added to the project a code generation is caused by the default custom tool and even after we remove it from the properties of the tt files the errors caused by the transformation are still in the Errors List (its something like visual glitch).
They disappear as soon as you save a file, navigate to other file or build the project but we do not want our users to see these errors and make any additional actions to get rid of them.
We tried to access the errors collection using the DTE and DTE2 classes like
DTE2 dte2 = (DTE2)this.project.DTE;
dte2.ToolWindows.TaskList;
or getting them from the ErrorListProvider provider as
var provider = new ErrorListProvider(this.ServiceProvider);
var tasks = provider.Tasks;
but the TaskList is not containing these errors - may be the reason is that they are transformation errors not a compile ones.
Even more strange is that the DTE.Events.TaskListEvents.TaskAdded event is firing for each of the transformation errors but they cannot be found in the TaskList. Also calling the Delete() method of the errors got from the TaskAdded event is not removing them from the errors list.
We also tried to programmatically navigate through the files or save the tamplates but it is not refreshing the errors list like when doing it manually.
How can we refresh the ErrorList or tell Visual Studio not to add a Custom Tool setting when we add the templates to the Project?
P.S. We do not want to force a build of the project of the clients (it is removing the errors but it is not applicable for us).
We found a dirty workaround to get rid of the errors.
We generate the template files with their basic template content (the one below) which is valid for the default TextTemplatingFileGenerator and the initial code generation is not causing any errors.
<## template debug="true" hostSpecific="true" #>
<## output extension=".cs" #>
<## Assembly Name="System.Core" #>
<## Assembly Name="System.Windows.Forms" #>
<## import namespace="System" #>
<#
// This is a temporary content valid for the TextTemplatingFileGenerator.
#>
Then after removing the custom tool setting we replace the content with the real one and everything is working as expected because the files are already in the Project and there are not any other transformations without a custom tool.
Not the best solution but we were not able to find better. I hope this helps.

Multi-targeted WP7.1/WP8 app with Windows Phone Toolkit (Panorama / LongListSelector)

Was wondering if someone had a good idea of how to handle this.
In WP7.1, we can utilize the excellent Windows Phone Toolkit to include some useful controls such as LongListSelector and Panorama. These are part of the Microsoft.Phone.Controls.Toolkit assembly.
In WP8, we do not need the toolkit for those two controls because they're part of the official Microsoft.Phone.Controls assembly.
I have multi-targeted my app so that I have two phone projects, WP71 and WP80, where I link files in WP80 to files in WP71.
This works great until I try to use the Panorama or LongListSelector control in a XAML page. In the WP80 project, if I reference the WP80 DLL of the phone toolkit, it does not include the two aforementioned controls because, surprise, they're already present.
The issue is, WP71 needs the namespace declaration at the top of the XAML and the namespace is different for both projects.
WP71:
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
<toolkit:Panorama />
WP80:
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
<phone:Panorama />
I cannot build the projects because each project thinks the namespace is incorrect if I just use one because they need to point to different assemblies.
I don't think I can use compile constants in my XAML, otherwise that would be a fix.
My workaround was originally to just reference the older WP71 DLL in my WP80 project. But other 3rd party libraries bind against the official 8.0 SDK DLL (Caliburn, in my case) so it causes problems.
How can I solve this pickle? The only idea off the top of my head was to resort to code-behind to create the instance of the control :( Is there a better way?
Don't use a link, create a separate view for each.
Another solution might be to create a PanoramaEx control in each of the relative projects and inherit from Panorama. Then the view would reference the PanoramaEx control and you could still use a link to a single view. That's if both UI projects have the same namespace.
Edit: isn't panorama for WP7 in the namespace:
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
I do use my initial solution for ProgressBar and PerformanceProgressBar, I have a ProgressBarEx in each UI project, the WP7 one inherits from ProgressBar and the WP8 one inherits from PerformanceProgressBar and then in the views I reference ProgressBarEx.
Might not be the most elegant solution, but you can try to use a T4 file (.tt file) to generate both targets.
<## template language="C#" hostspecific="true"#>
<## output extension=".xaml"#>
<## assembly name="EnvDTE" #>
<phone:PhoneApplicationPage
x:Class="PhoneAppDemo.Pages.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
<# IServiceProvider serviceProvider = (IServiceProvider)Host;
EnvDTE.DTE dte = (EnvDTE.DTE)serviceProvider.GetService(typeof(EnvDTE.DTE));
var configName = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
if (configName == "WP7") { #>
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
<# }else{ #>
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
<# } #>
>
<# include file="Page.xaml" #>
</phone:PhoneApplicationPage>
In this example, the inner content of the Page is in "Page.xaml". We just encapsulate it in <phone:PhoneApplicationPage> at processor time, based on the target name (usually Debug and Release, but in this example we assumed there was a target WP7).
For other stuff related to a multi-targeted silverlight app, you can always read Maintaining a WP7 and WP8 version of a same Silverlight application.

Finding T4 text template class code

T4 text templates can be used to generate not only code but also any kind of text with visual studio.
I've read blogs and tutorials about T4 and as far as I can understand, visual studio dynamically builds a class in the background, compiles and runs the code in that class to build the text output.
Is it possible to see the source code of that class?
Yes, the easiest way is to change the Custom Tool in the properties window when the template file is selected in Solution Explorer.
By default, it will be 'TextTemplatingFileGenerator'.
If you change the custom tool to 'TextTemplatingFilePreprocessor' you'll get the underlying template class instead of the template output generated into your project.
To be precise, this code won't be exactly the same as that which is run under the covers, but it will be very close.
If you need the absolute exact code, you should leave the custom tool alone, but set the debug="true" flag on your <## template #> directive. This will then leave the generated code sitting around in a random named '.cs' or 'vb' file in your %TEMP% directory. Just sort the directory by time and it should be up at the top.

How to automatically run custom tool for T4 file when another file is saved

Is there a way to automatically run the T4 transform when another file is saved?
The AutoRunCustomTool Visual Studio extension was created to address this exact scenario.
It seems like T4 Toolbox is not available for VS2012. However there is now a feature in tangible T4 Editor that allows you to simply add a auto-transformed template to any exisitng file in your solution so that when the parent file is saved the dependend t4 file is transformed. See here:
http://t4-editor.tangible-engineering.com/blog/dependent-t4-templates.html
You can do that with T4 Toolbox. Select the file in Solution Explorer and set the Custom Tool Template in the Properties window.
I get this answer form How can set the custom tool property of an xml file to a T4 file?

what is and where can I find MvcTextTemplateHost

I would like to know what this is MvcTextTemplateHost. I have this in my create.tt but I cant find it in my bin folder (searching with object viewer). I read up and found out it's in my
VisualStudio.Extensions.web.dll but I cant find this dll
I've read this
T4 References for 'MvcTextTemplateHost' and 'VisualStudio'.
I would just like to know what properties and methods this class has. I would love a t4 text editor. I installed a few but nothing gives me intellisense for this class thank you.
MvcTextTemplateHost is "Host" of MVC 3.0 (Add>View and Add>Controller) Dialog and maintain user interactions:
so it is not available outside of the tool. When you provide "Scaffolding" template (a .tt file) a manager passes these user inputs to host so host will have those properties.
The class is packaged in:
($VSDIR)\Common7\IDE\Microsoft.VisualStudio.Web.Mvc.3.01.dll
Hope it helps.
In my case the solution was. add these line en controllerWithContext.tt
<## assembly name="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Microsoft.VisualStudio.Web.Mvc.3.01.dll" #>
next to:
<## import namespace="System.Reflection" #>
before:
<## import namespace="Microsoft.VisualStudio.Web.Mvc.Scaffolding.BuiltIn" #>
good luck
You can find all .tt files in VS installation direction, for example to get MVC4 .tt files, go to: ($VSDir)\Common7\IDE\ItemTemplates\CSharp\Web\MVC 4\CodeTemplates
To get the list of the properties of MvcTextTemplateHost, as they are dynamic, you can add the following code to your .tt file:
<#
Type myType = mvcHost.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
foreach (PropertyInfo prop in props)
{
#>
<#= prop.Name #>
<#
}
#>
I ran it as I create a List View in MVC4, and some of the properties that came up are:
ViewName
IsPartialView
IsContentPage
ReferenceScriptLibraries
AutoEventWireup
MasterPageFile
...
I had the same problem after installing the T4 templates for modifying Visual Studio's auto generated CRUD pages described in this question: How do I create my own Scaffold Template in ASP.NET MVC 3?
The solution for me was just to just close Visual Studio 2012 and say Yes to saving the solution. When I reopened it everything compiled fine again, magically. The comments on this answer suggest this has worked for similar situations: https://stackoverflow.com/a/13816299/176877

Resources