diff --git a/.gitignore b/.gitignore
index f3ccef0..4800d1c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -359,3 +359,4 @@ MigrationBackup/
/src/FormsTemplatesCLI/Install-Template.bat
/src/FormsTemplatesCLI/Install-Debug-Template.bat
/src/FormsTemplatesCLI/Install-Release-Template.bat
+/xamarin-forms-templates.code-workspace
diff --git a/README.md b/README.md
index b5e86d3..eceddfb 100644
--- a/README.md
+++ b/README.md
@@ -123,14 +123,27 @@ And `-na` denotes the namespace under which the file is to be created (Can also
#### Generic Item Templates:
+![Xamarin.Forms Generic Item Templates by Vijay Anand E G](images/xamarin-forms-add-new-item.png)
+
* A revolutionary generic item template, in XAML and C#, for creating items of any type
-* And it is named `forms-item` and `forms-item-cs`
+* Supported both within the VS2022 IDE and CLI
+* On CLI, it is named as `forms-item` and `forms-item-cs`
+* The same set of parameters is defined in the UI as `Dropdown`, `TextBox` and `CheckBox` for ease of use
* Both need one required parameter, `-b` / `--base`, the base type
* Optionally takes another parameter, `-g` / `--generic`, to specify the generic base type
* In addition, the XAML template takes one more parameter, `-xo` / `--xaml-only`, when defined, generates only the XAML definition
+* Frequently used base types are loaded in the Editable dropdown, user can also enter their value here
+* Ensure the values are entered in Pascal notation. XAML templates support XML namespace prefix, quite like how it is used in real world (`xct:Popup`)
+* The one big advantage of using this on IDE is the relative namespace to the folder where the item is created whereas on CLI, this defaults to the root namespace. As relative namespace resolution is yet to be fully supported by the CLI templating engine and is actively tracked [here](https://github.com/dotnet/templating/issues/6010)
+
+![Xamarin.Forms Generic Item Dialog by Vijay Anand E G](images/xamarin-forms-generic-item-dialog.png)
*Note: Namespace resolution in both XAML and C# files is left to the user as deriving them with the template is outside its scope.*
+*Tip 1: For XAML template, pass the `xmlns` scope, like `xct:Popup`, as part of the input parameter value and it'll be used appropriately in the generated source files.*
+
+*Tip: Tip: Use `local` scope to refer to the types in the same directory like `Views`. For e.g., `local:BasePage`.*
+
Example:
```shell
dotnet new forms-item -n ThemePopup -b xct:Popup -p:na MyApp.Views
diff --git a/images/xamarin-forms-add-new-item.png b/images/xamarin-forms-add-new-item.png
new file mode 100644
index 0000000..5e7547d
Binary files /dev/null and b/images/xamarin-forms-add-new-item.png differ
diff --git a/images/xamarin-forms-class-library-options.png b/images/xamarin-forms-class-library-options.png
index eba611a..f011580 100644
Binary files a/images/xamarin-forms-class-library-options.png and b/images/xamarin-forms-class-library-options.png differ
diff --git a/images/xamarin-forms-generic-item-dialog.png b/images/xamarin-forms-generic-item-dialog.png
new file mode 100644
index 0000000..03dea8f
Binary files /dev/null and b/images/xamarin-forms-generic-item-dialog.png differ
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/CustomActionWizard.cs b/src/Extensions/XFormsTemplates/XFormsTemplates/CustomActionWizard.cs
new file mode 100644
index 0000000..b0ddea4
--- /dev/null
+++ b/src/Extensions/XFormsTemplates/XFormsTemplates/CustomActionWizard.cs
@@ -0,0 +1,129 @@
+using EnvDTE;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.TemplateWizard;
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace VijayAnand.XFormsTemplates
+{
+ public class CustomActionWizard : IWizard
+ {
+ bool xamlOnly;
+ bool userCancel;
+
+ /// This method is called before opening any item that has the OpenInEditor attribute.
+ public void BeforeOpeningFile(ProjectItem projectItem)
+ {
+
+ }
+
+ public void ProjectFinishedGenerating(Project project)
+ {
+
+ }
+
+ /// This method is only called for item templates, not for project templates.
+ public void ProjectItemFinishedGenerating(ProjectItem projectItem)
+ {
+
+ }
+
+ /// This method is called after the project is created.
+ public void RunFinished()
+ {
+
+ }
+
+ public async void RunStarted(object automationObject,
+ Dictionary replacementsDictionary,
+ WizardRunKind runKind,
+ object[] customParams)
+ {
+ try
+ {
+ //ThreadHelper.ThrowIfNotOnUIThread();
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+
+ if (runKind == WizardRunKind.AsNewItem)
+ {
+ if (replacementsDictionary.ContainsKey("$basetype$"))
+ {
+ var xamlItem = replacementsDictionary.ContainsKey("$xaml$");
+ var window = new GenericItemDialog(xamlItem);
+ var result = window.ShowDialog();
+
+ if (result is true)
+ {
+ xamlOnly = window.XamlOnly;
+ replacementsDictionary["$xaml$"] = xamlOnly.ToString().ToLowerInvariant();
+
+ var baseType = window.BaseType;
+ var genericType = window.GenericType;
+ var baseTypeCS = baseType.Contains(":") ? baseType.Substring(baseType.IndexOf(':') + 1) : baseType;
+ var genericTypeCS = genericType.Contains(":") ? genericType.Substring(genericType.IndexOf(':') + 1) : genericType;
+
+ if (!string.IsNullOrEmpty(baseType))
+ {
+ if (xamlItem)
+ {
+ replacementsDictionary["$basetype$"] = baseType;
+
+ if (string.IsNullOrEmpty(genericTypeCS))
+ {
+ replacementsDictionary["$csbasetype$"] = baseTypeCS;
+ replacementsDictionary["$generic$"] = bool.FalseString.ToLowerInvariant();
+ }
+ else
+ {
+ replacementsDictionary["$csbasetype$"] = $"{baseTypeCS}<{genericTypeCS}>";
+ replacementsDictionary["$generic$"] = bool.TrueString.ToLowerInvariant();
+ replacementsDictionary["$typearg$"] = genericType;
+ }
+ }
+ else
+ {
+ // For C# template, basetype is the parameter name
+ if (string.IsNullOrEmpty(genericTypeCS))
+ {
+ replacementsDictionary["$basetype$"] = baseTypeCS;
+ }
+ else
+ {
+ replacementsDictionary["$basetype$"] = $"{baseTypeCS}<{genericTypeCS}>";
+ }
+ }
+ }
+ }
+ else
+ {
+ userCancel = true;
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ // Log the exception.
+ await ex.LogAsync();
+ }
+ }
+
+ /// This method is only called for item templates, not for project templates.
+ public bool ShouldAddProjectItem(string filePath)
+ {
+ if (userCancel)
+ {
+ return false;
+ }
+ else if (filePath.EndsWith(".xaml.cs"))
+ {
+ return !xamlOnly;
+ }
+ else
+ {
+ return !File.Exists(filePath);
+ }
+ }
+ }
+}
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/GenericItemDialog.xaml b/src/Extensions/XFormsTemplates/XFormsTemplates/GenericItemDialog.xaml
new file mode 100644
index 0000000..66a9673
--- /dev/null
+++ b/src/Extensions/XFormsTemplates/XFormsTemplates/GenericItemDialog.xaml
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Application
+ ContentPage
+ ContentView
+ FlyoutPage
+ Grid
+ NavigationPage
+ ResourceDictionary
+ Shell
+ StackLayout
+ SwipeView
+ TabbedPage
+
+
+
+
+
+
+
+
+
+ © 2024 Vijay Anand E G
+
+
+ egvijayanand.in
+
+
+
+
+
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/GenericItemDialog.xaml.cs b/src/Extensions/XFormsTemplates/XFormsTemplates/GenericItemDialog.xaml.cs
new file mode 100644
index 0000000..e1fc2df
--- /dev/null
+++ b/src/Extensions/XFormsTemplates/XFormsTemplates/GenericItemDialog.xaml.cs
@@ -0,0 +1,191 @@
+using Microsoft.VisualStudio.PlatformUI;
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Navigation;
+
+namespace VijayAnand.XFormsTemplates
+{
+ public partial class GenericItemDialog : DialogWindow
+ {
+ const string BasePlaceholderText = "Enter base type (in Pascal notation)";
+ const string GenericPlaceholderText = "Enter generic base type (in Pascal notation)";
+ const string CSharpTypeExpression = @"^([A-Z]\w*)$";
+ const string XamlTypeExpression = @"^([a-zA-Z0-9]+\:)?([A-Z]\w*)$";
+
+ readonly bool xamlTemplate;
+ readonly Brush foreColor;
+ readonly Brush placeholderColor = Brushes.Gray;
+
+ public GenericItemDialog(bool xamlTemplate = true)
+ {
+ InitializeComponent();
+ this.xamlTemplate = xamlTemplate;
+ foreColor = cboBaseType.Foreground;
+ chkXamlOnly.Visibility = xamlTemplate ? Visibility.Visible : Visibility.Collapsed;
+
+ if (xamlTemplate)
+ {
+ cboBaseType.Items.Add(new ComboBoxItem() { Content = "xct:Popup" });
+ cboBaseType.Items.Add(new ComboBoxItem() { Content = "vw:FormsPage" });
+ }
+ else
+ {
+ cboBaseType.Items.Add(new ComboBoxItem() { Content = "Popup" });
+ cboBaseType.Items.Add(new ComboBoxItem() { Content = "FormsPage" });
+ }
+ }
+
+ public string BaseType { get; private set; }
+
+ public string GenericType { get; private set; }
+
+ public bool XamlOnly { get; private set; }
+
+ private void OnAcceptClick(object sender, RoutedEventArgs e)
+ {
+ XamlOnly = chkXamlOnly.Visibility == Visibility.Visible && chkXamlOnly.IsChecked is true;
+ BaseType = cboBaseType.Text == BasePlaceholderText ? string.Empty : cboBaseType.Text.Trim();
+ GenericType = txtGenericType.Text == GenericPlaceholderText ? string.Empty : txtGenericType.Text.Trim();
+
+ if (string.IsNullOrEmpty(BaseType))
+ {
+ ShowMessage("Not a valid value for base type.");
+ cboBaseType.Focus();
+ return;
+ }
+
+ if (xamlTemplate)
+ {
+ if (!Regex.IsMatch(BaseType, XamlTypeExpression))
+ {
+ ShowMessage("Not a valid value for C# base type.");
+ cboBaseType.Focus();
+ return;
+ }
+ else if (!string.IsNullOrEmpty(GenericType) && !Regex.IsMatch(GenericType, XamlTypeExpression))
+ {
+ ShowMessage("Not a valid value for C# generic base type.");
+ txtGenericType.Focus();
+ return;
+ }
+ }
+ else
+ {
+ if (BaseType.Contains(':') || !Regex.IsMatch(BaseType, CSharpTypeExpression))
+ {
+ ShowMessage("Not a valid value for C# base type.");
+ cboBaseType.Focus();
+ return;
+ }
+ else if (!string.IsNullOrEmpty(GenericType)
+ && (GenericType.Contains(':') || !Regex.IsMatch(GenericType, CSharpTypeExpression)))
+ {
+ ShowMessage("Not a valid value for C# generic base type.");
+ txtGenericType.Focus();
+ return;
+ }
+ }
+
+ DialogResult = true;
+ Close();
+ }
+
+ private void OnCancelClick(object sender, RoutedEventArgs e)
+ {
+ DialogResult = false;
+ Close();
+ }
+
+ private void OnBaseTypeGotFocus(object sender, RoutedEventArgs e)
+ {
+ if (sender is ComboBox dropdown)
+ {
+ if (dropdown.Text.Trim() == BasePlaceholderText)
+ {
+ dropdown.Text = string.Empty;
+ dropdown.Foreground = foreColor;
+ }
+ }
+ }
+
+ private void OnBaseTypeLostFocus(object sender, RoutedEventArgs e)
+ {
+ if (sender is ComboBox dropdown)
+ {
+ if (dropdown.Text == string.Empty)
+ {
+ dropdown.Text = BasePlaceholderText;
+ dropdown.Foreground = placeholderColor;
+ }
+ }
+ }
+
+ private void OnGenericTypeGotFocus(object sender, RoutedEventArgs e)
+ {
+ if (sender is TextBox entry)
+ {
+ if (entry.Text.Trim() == GenericPlaceholderText)
+ {
+ entry.Text = string.Empty;
+ entry.Foreground = foreColor;
+ }
+ }
+ }
+
+ private void OnGenericTypeLostFocus(object sender, RoutedEventArgs e)
+ {
+ if (sender is TextBox entry)
+ {
+ if (entry.Text == string.Empty)
+ {
+ entry.Text = GenericPlaceholderText;
+ entry.Foreground = placeholderColor;
+ }
+ }
+ }
+
+ private void OnWindowLoaded(object sender, RoutedEventArgs e)
+ {
+ txtGenericType.Foreground = placeholderColor;
+ txtGenericType.Text = GenericPlaceholderText;
+ cboBaseType.Focus();
+ }
+
+ private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
+ {
+ Process.Start(new ProcessStartInfo()
+ {
+ FileName = e.Uri.AbsoluteUri,
+ UseShellExecute = true
+ });
+
+ e.Handled = true;
+ }
+
+ private void OnWindowKeyDown(object sender, KeyEventArgs e)
+ {
+ if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt)
+ {
+ if (Keyboard.IsKeyDown(Key.B))
+ {
+ cboBaseType.Focus();
+ }
+ else if (Keyboard.IsKeyDown(Key.G))
+ {
+ txtGenericType.Focus();
+ }
+ }
+ }
+
+ private static void ShowMessage(string message)
+ {
+ MessageBox.Show(message, "Xamarin.Forms Generic Item", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+}
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/ItemTemplates/FormsItem.zip b/src/Extensions/XFormsTemplates/XFormsTemplates/ItemTemplates/FormsItem.zip
new file mode 100644
index 0000000..b01d1d5
Binary files /dev/null and b/src/Extensions/XFormsTemplates/XFormsTemplates/ItemTemplates/FormsItem.zip differ
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/ItemTemplates/FormsItemCS.zip b/src/Extensions/XFormsTemplates/XFormsTemplates/ItemTemplates/FormsItemCS.zip
new file mode 100644
index 0000000..5daaab5
Binary files /dev/null and b/src/Extensions/XFormsTemplates/XFormsTemplates/ItemTemplates/FormsItemCS.zip differ
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/Properties/AssemblyInfo.cs b/src/Extensions/XFormsTemplates/XFormsTemplates/Properties/AssemblyInfo.cs
index dec926c..d347ae6 100644
--- a/src/Extensions/XFormsTemplates/XFormsTemplates/Properties/AssemblyInfo.cs
+++ b/src/Extensions/XFormsTemplates/XFormsTemplates/Properties/AssemblyInfo.cs
@@ -1,7 +1,11 @@
-using System.Reflection;
+using Microsoft.VisualStudio.Shell;
+using System.Reflection;
using System.Runtime.InteropServices;
using VijayAnand.XFormsTemplates;
+// For Visual Studio to locate and load the component assembly during runtime
+[assembly: ProvideCodeBase(AssemblyName = "VijayAnand.XFormsTemplates")]
+
[assembly: AssemblyTitle(Vsix.Name)]
[assembly: AssemblyDescription(Vsix.Description)]
[assembly: AssemblyConfiguration("")]
@@ -13,10 +17,11 @@
[assembly: ComVisible(false)]
-[assembly: AssemblyVersion(Vsix.Version)]
-[assembly: AssemblyFileVersion(Vsix.Version)]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyInformationalVersion("1.0.0.0")]
namespace System.Runtime.CompilerServices
{
public class IsExternalInit { }
-}
\ No newline at end of file
+}
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/XFormsTemplates.csproj b/src/Extensions/XFormsTemplates/XFormsTemplates/XFormsTemplates.csproj
index b7eea42..fb58b10 100644
--- a/src/Extensions/XFormsTemplates/XFormsTemplates/XFormsTemplates.csproj
+++ b/src/Extensions/XFormsTemplates/XFormsTemplates/XFormsTemplates.csproj
@@ -4,7 +4,13 @@
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
latest
-
+
+ true
+
+
+ vijayanand.snk
+
+
Debug
AnyCPU
@@ -15,7 +21,7 @@
Properties
VijayAnand.XFormsTemplates
VijayAnand.XFormsTemplates
- v4.8
+ v4.8.1
true
true
true
@@ -45,7 +51,11 @@
4
-
+
+
+ GenericItemDialog.xaml
+
+
True
True
@@ -73,7 +83,17 @@
true
ItemTemplates\Xamarin.Forms
-
+
+
+ Always
+ true
+ ItemTemplates\Xamarin.Forms\All-in-One
+
+
+ Always
+ true
+ ItemTemplates\Xamarin.Forms\All-in-One
+
Designer
VsixManifestGenerator
@@ -95,31 +115,44 @@
PreserveNewest
true
+
-
-
+
+
+
+
+
-
- compile; build; native; contentfiles; analyzers; buildtransitive
+
+
+ 17.5.33428.366
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
+ 13.0.3
+
+
+
+
+ MSBuild:Compile
+ Designer
+
-
-
-
+
+
- <_TemplatePackage Include="Assets\*.nupkg"/>
+ <_TemplatePackage Include="Assets\*.nupkg" />
-
-
+
+
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/release-notes.txt b/src/Extensions/XFormsTemplates/XFormsTemplates/release-notes.txt
index e60e378..3852daa 100644
--- a/src/Extensions/XFormsTemplates/XFormsTemplates/release-notes.txt
+++ b/src/Extensions/XFormsTemplates/XFormsTemplates/release-notes.txt
@@ -1,5 +1,23 @@
-What's new in ver. 1.6.0.0:
+Join me on Developer Thoughts (https://egvijayanand.in/), an exclusive blog for articles on Xamarin.Forms, .NET MAUI, and Blazor.
+
+What's new in ver. 1.7.0.0:
---------------------------
+A revolutionary Xamarin.Forms generic item template, in XAML and C#, for creating items of any type from within Visual Studio 2022 IDE.
+
+Both need one required input, the base type (select a value from the predefined ones or enter a value).
+
+Optionally takes another input, to specify the generic base type.
+
+In addition, the XAML template takes one more input (xaml only), when opted, generates only XAML definition.
+
+Note: Namespace resolution in both XAML and C# file is left to the user as deriving them with the template is outside its scope.
+
+Tip: For XAML template, pass the xmlns scope as part of the input parameter value and it'll be used appropriately in the generated source files.
+
+Tip: Tip: Use local scope to refer to the types in the same directory like Views. For example, local:BasePage
+
+v1.6.0.0:
+
1. Introduced an option to add a reference to Xamarin.Essentials.Interfaces NuGet package, an explicit option.
v1.5.0.0:
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/source.extension.cs b/src/Extensions/XFormsTemplates/XFormsTemplates/source.extension.cs
index fd4503c..666dad5 100644
--- a/src/Extensions/XFormsTemplates/XFormsTemplates/source.extension.cs
+++ b/src/Extensions/XFormsTemplates/XFormsTemplates/source.extension.cs
@@ -11,7 +11,7 @@ internal sealed partial class Vsix
public const string Name = "Xamarin.Forms Project and Item Templates";
public const string Description = @"Xamarin.Forms Project and Item Templates for building native apps for iOS, Android, UWP, macOS, Tizen from a single, shared C# codebase.";
public const string Language = "en-US";
- public const string Version = "1.6.0.0";
+ public const string Version = "1.7.0.0";
public const string Author = "Vijay Anand E G";
public const string Tags = "Xamarin.Forms, Mobile, iOS, Android, UWP, Desktop, Windows, Templates, Shell, Library, Visual Studio, Resource Dictionary, Xamarin, macOS, Tizen";
}
diff --git a/src/Extensions/XFormsTemplates/XFormsTemplates/source.extension.vsixmanifest b/src/Extensions/XFormsTemplates/XFormsTemplates/source.extension.vsixmanifest
index 3bc44e1..43712c9 100644
--- a/src/Extensions/XFormsTemplates/XFormsTemplates/source.extension.vsixmanifest
+++ b/src/Extensions/XFormsTemplates/XFormsTemplates/source.extension.vsixmanifest
@@ -1,7 +1,7 @@
-
+
Xamarin.Forms Project and Item Templates
Xamarin.Forms Project and Item Templates for building native apps for iOS, Android, UWP, macOS, Tizen from a single, shared C# codebase.
https://egvijayanand.in/category/xamarin/
@@ -13,7 +13,7 @@
Xamarin.Forms, Mobile, iOS, Android, UWP, Desktop, Windows, Templates, Shell, Library, Visual Studio, Resource Dictionary, Xamarin, macOS, Tizen
-
diff --git a/src/ItemTemplates/FormsItem/FormsItem.vstemplate b/src/ItemTemplates/FormsItem/FormsItem.vstemplate
new file mode 100644
index 0000000..7128df5
--- /dev/null
+++ b/src/ItemTemplates/FormsItem/FormsItem.vstemplate
@@ -0,0 +1,27 @@
+
+
+ FormsItem.xaml
+ Generic Item
+ Generic Xamarin.Forms item template in XAML.
+ CSharp
+ Xamarin.Forms
+ 110
+ __TemplateIcon.ico
+
+
+
+ FormsItem.xaml
+ FormsItem.xaml.cs
+
+
+
+
+
+
+
+
+
+ VijayAnand.XFormsTemplates, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7550554040ebdd44
+ VijayAnand.XFormsTemplates.CustomActionWizard
+
+
diff --git a/src/ItemTemplates/FormsItem/FormsItem.xaml b/src/ItemTemplates/FormsItem/FormsItem.xaml
new file mode 100644
index 0000000..d540023
--- /dev/null
+++ b/src/ItemTemplates/FormsItem/FormsItem.xaml
@@ -0,0 +1,18 @@
+
+$if$ ($xaml$ == true)
+
+$endif$
+<$basetype$
+$if$ ($xaml$ == false)
+ x:Class="$rootnamespace$.$safeitemname$"
+$endif$
+ xmlns="http://xamarin.com/schemas/2014/forms"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:d="http://xamarin.com/schemas/2014/forms/design"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:local="clr-namespace:$rootnamespace$"
+$if$ ($generic$ == true)
+ x:TypeArguments="$typearg$"
+$endif$
+ mc:Ignorable="d">
+$basetype$>
diff --git a/src/ItemTemplates/FormsItem/FormsItem.xaml.cs b/src/ItemTemplates/FormsItem/FormsItem.xaml.cs
new file mode 100644
index 0000000..80ac9f5
--- /dev/null
+++ b/src/ItemTemplates/FormsItem/FormsItem.xaml.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xamarin.Forms;
+using Xamarin.Forms.Xaml;
+
+namespace $rootnamespace$
+{
+ [XamlCompilation(XamlCompilationOptions.Compile)]
+ public partial class $safeitemname$ : $csbasetype$
+ {
+ public $safeitemname$()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/src/ItemTemplates/FormsItem/__TemplateIcon.ico b/src/ItemTemplates/FormsItem/__TemplateIcon.ico
new file mode 100644
index 0000000..aae70d3
Binary files /dev/null and b/src/ItemTemplates/FormsItem/__TemplateIcon.ico differ
diff --git a/src/ItemTemplates/FormsItemCS/FormsItemCS.cs b/src/ItemTemplates/FormsItemCS/FormsItemCS.cs
new file mode 100644
index 0000000..c49c8d2
--- /dev/null
+++ b/src/ItemTemplates/FormsItemCS/FormsItemCS.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xamarin.Forms;
+
+namespace $rootnamespace$
+{
+ public partial class $safeitemname$ : $basetype$
+ {
+ public $safeitemname$()
+ {
+
+ }
+ }
+}
diff --git a/src/ItemTemplates/FormsItemCS/FormsItemCS.vstemplate b/src/ItemTemplates/FormsItemCS/FormsItemCS.vstemplate
new file mode 100644
index 0000000..c96e9cc
--- /dev/null
+++ b/src/ItemTemplates/FormsItemCS/FormsItemCS.vstemplate
@@ -0,0 +1,22 @@
+
+
+ FormsItem.cs
+ Generic Item (C#)
+ Generic Xamarin.Forms item template in C#.
+ CSharp
+ Xamarin.Forms
+ 110
+ __TemplateIcon.ico
+
+
+
+ FormsItemCS.cs
+
+
+
+
+
+ VijayAnand.XFormsTemplates, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7550554040ebdd44
+ VijayAnand.XFormsTemplates.CustomActionWizard
+
+
diff --git a/src/ItemTemplates/FormsItemCS/__TemplateIcon.ico b/src/ItemTemplates/FormsItemCS/__TemplateIcon.ico
new file mode 100644
index 0000000..aae70d3
Binary files /dev/null and b/src/ItemTemplates/FormsItemCS/__TemplateIcon.ico differ