Skip to content

Commit

Permalink
Merge pull request #24 from egvijayanand/working
Browse files Browse the repository at this point in the history
Generic and MVVM Item Templates
egvijayanand authored Jan 16, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents 8f858b0 + 231d584 commit d47c88e
Showing 23 changed files with 671 additions and 11 deletions.
81 changes: 73 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -65,6 +65,10 @@ Explicit option:

|Item|Template Name|
|:---:|:---:|
|[Xamarin.Forms Item (XAML)](#generic-item-templates)|forms-item|
|[Xamarin.Forms Item (C#)](#generic-item-templates)|forms-item-cs|
|[ContentPage and ViewModel (XAML)](#mvvm-item-templates)|forms-mvvm|
|[ContentPage and ViewModel (C#)](#mvvm-item-templates)|forms-mvvm-cs|
|ContentPage (XAML)|forms-page|
|ContentPage (C#)|forms-page-cs|
|ContentView (XAML)|forms-view|
@@ -117,43 +121,104 @@ And `-na` denotes the namespace under which the file is to be created (Can also

*While working with .NET 7 or higher SDK, the namespace parameter in short notation needs to be passed as `-p:na` (i.e., it needs to be prefixed with `-p:`).*

Page:
#### Generic Item Templates:

* 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`
* 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

*Note: Namespace resolution in both XAML and C# files is left to the user as deriving them with the template is outside its scope.*

Example:
```shell
dotnet new forms-item -n ThemePopup -b xct:Popup -p:na MyApp.Views
```

**Output:** `ThemePopup.xaml` and `ThemePopup.xaml.cs`

```cs
public partial class ThemePopup : Popup {}
```

```shell
dotnet new forms-item -n SearchPage -b FormsPage -g SearchViewModel -p:na MyApp.Views
```

**Output:** `SearchPage.xaml` and `SearchPage.xaml.cs`

```cs
public partial class SearchPage : FormsPage<SearchViewModel> {}
```

#### MVVM Item Templates:

* Introduced an item template to generate Page and its ViewModel in a single command, available for both XAML and C#
* The Page will be generated in the Views folder and ViewModel will be generated in the ViewModels folder
* Can also be overridden to generate in the same folder with the `-sf` | `--same-folder` option
* The ViewModels are generated with the base class titled `BaseViewModel` *(implementation left to the user)*
* Including [CommunityToolkit.Mvvm](https://www.nuget.org/packages/CommunityToolkit.Mvvm), an officially supported NuGet package, would be the best fit as it makes it easy to work with the MVVM design pattern
* And it's recommended to use this MVVM template from the project root. So that output is aligned to the folder structure

*Note: Don't suffix anything to the name, it'll be included automatically.*

```shell
dotnet new forms-mvvm -n Login -p:na MyApp
```
```shell
dotnet new forms-mvvm-cs -n Search -p:na MyApp
```

**Output Structure:**

XAML:

ViewModels
&emsp;LoginViewModel.cs
Views
&emsp;LoginPage.xaml
&emsp;LoginPage.xaml.cs

C#:

ViewModels
&emsp;SearchViewModel.cs
Views
&emsp;SearchPage.cs

**Page:**
```shell
dotnet new forms-page -n Login -na MyApp.Views
```
```shell
dotnet new forms-page-cs -n Home -na MyApp.Views
```

View:

**View:**
```shell
dotnet new forms-view -n Card -na MyApp.Views
```
```shell
dotnet new forms-view-cs -n Order -na MyApp.Views
```

Shell:

**Shell:**
```shell
dotnet new forms-shell -n App -na MyApp
```
```shell
dotnet new forms-shell-cs -n Mobile -na MyApp
```

Resource Dictionary:
**Resource Dictionary:**

With C# code-behind file:

```shell
dotnet new forms-resdict -n DefaultTheme -na MyApp.Themes
```

Without C# code-behind file - Xaml only (The option to be specified is `-xo` or `--xaml-only`):

```shell
dotnet new forms-resdict -n DarkTheme -na MyApp.Themes -xo
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "http://json.schemastore.org/dotnetcli.host",
"symbolInfo": {
"namespace": {
"shortName": "na"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$schema": "http://json.schemastore.org/vs-2017.3.host"
}
99 changes: 99 additions & 0 deletions src/FormsTemplatesCLI/FormsItem/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"$schema": "https://json.schemastore.org/template",
"author": "Vijay Anand E G",
"defaultName": "FormsItem1",
"classifications": [
"Xamarin",
"Android",
"iOS",
"macOS",
"Windows",
"Xaml"
],
"identity": "VijayAnand.FormsItem",
"groupIdentity": "VijayAnand.FormsTemplates.Item.Xaml",
"description": "An item template for Xamarin.Forms Item in XAML",
"name": "Xamarin.Forms Item",
"shortName": "forms-item",
"sourceName": "FormsItem.1",
"primaryOutputs": [
{
"path": "FormsItem.1.xaml"
},
{
"condition": "(!XamlOnly)",
"path": "FormsItem.1.xaml.cs"
}
],
"tags": {
"language": "C#",
"type": "item"
},
"symbols": {
"base": {
"isRequired": true,
"type": "parameter",
"description": "Base type for the item.",
"datatype": "text",
"replaces": "ContentPage"
},
"generic": {
"type": "parameter",
"description": "Generic base type for the item.",
"datatype": "text",
"defaultValue": "",
"replaces": "TObject"
},
"namespace": {
"type": "parameter",
"datatype": "text",
"description": "namespace for the generated code",
"replaces": "MyApp.Namespace"
},
"xaml-only": {
"type": "parameter",
"datatype": "bool",
"default": "false",
"description": "If true, the output is generated without a C# code-behind file."
},
"TypeRename": {
"type": "derived",
"valueSource": "base",
"valueTransform": "ValueWithoutScope",
"replaces": "ContentView"
},
"ContextRename": {
"type": "derived",
"valueSource": "generic",
"valueTransform": "ValueWithoutScope",
"replaces": "TContext"
},
"IsGeneric": {
"type": "computed",
"value": "(generic != \"\")"
},
"XamlOnly": {
"type": "computed",
"value": "(xaml-only)"
}
},
"forms": {
"ValueWithoutScope": {
"identifier": "replace",
"pattern": "^.*\\:(?=[^\\:]+$)",
"replacement": ""
}
},
"sources": [
{
"modifiers": [
{
"condition": "(XamlOnly)",
"exclude": [
"FormsItem.1.xaml.cs"
]
}
]
}
]
}
47 changes: 47 additions & 0 deletions src/FormsTemplatesCLI/FormsItem/FormsItem.1.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--#if (XamlOnly)-->
<?xaml-comp compile="true" ?>
<!--#if (IsGeneric)-->
<ContentPage
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:MyApp.Namespace"
x:TypeArguments="TObject"
mc:Ignorable="d">
</ContentPage>
<!--#else-->
<ContentPage
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:MyApp.Namespace"
mc:Ignorable="d">
</ContentPage>
<!--#endif-->
<!--#else-->
<!--#if (IsGeneric)-->
<ContentPage
x:Class="MyApp.Namespace.FormsItem__1"
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:MyApp.Namespace"
x:TypeArguments="TObject"
mc:Ignorable="d">
</ContentPage>
<!--#else-->
<ContentPage
x:Class="MyApp.Namespace.FormsItem__1"
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:MyApp.Namespace"
mc:Ignorable="d">
</ContentPage>
<!--#endif-->
<!--#endif-->
18 changes: 18 additions & 0 deletions src/FormsTemplatesCLI/FormsItem/FormsItem.1.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace MyApp.Namespace
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if IsGeneric
public partial class FormsItem__1 : ContentView<TContext>
#else
public partial class FormsItem__1 : ContentView
#endif
{
public FormsItem__1()
{
InitializeComponent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "http://json.schemastore.org/dotnetcli.host",
"symbolInfo": {
"namespace": {
"shortName": "na"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$schema": "http://json.schemastore.org/vs-2017.3.host"
}
54 changes: 54 additions & 0 deletions src/FormsTemplatesCLI/FormsItemCS/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"$schema": "https://json.schemastore.org/template",
"author": "Vijay Anand E G",
"defaultName": "FormsItem1",
"classifications": [
"Xamarin",
"Android",
"iOS",
"macOS",
"Windows",
"Code"
],
"identity": "VijayAnand.FormsItemCS",
"groupIdentity": "VijayAnand.FormsTemplates.Item.Code",
"description": "An item template for Xamarin.Forms Item in C#",
"name": "Xamarin.Forms Item (C#)",
"shortName": "forms-item-cs",
"sourceName": "FormsItem.1",
"primaryOutputs": [
{
"path": "FormsItem.1.cs"
}
],
"tags": {
"language": "C#",
"type": "item"
},
"symbols": {
"base": {
"isRequired": true,
"type": "parameter",
"description": "Base type for the item.",
"datatype": "text",
"replaces": "ContentPage"
},
"generic": {
"type": "parameter",
"description": "Generic base type for the item.",
"datatype": "text",
"defaultValue": "",
"replaces": "TObject"
},
"namespace": {
"type": "parameter",
"datatype": "text",
"description": "namespace for the generated code",
"replaces": "MyApp.Namespace"
},
"IsGeneric": {
"type": "computed",
"value": "(generic != \"\")"
}
}
}
16 changes: 16 additions & 0 deletions src/FormsTemplatesCLI/FormsItemCS/FormsItem.1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Xamarin.Forms;

namespace MyApp.Namespace
{
#if IsGeneric
public partial class FormsItem__1 : ContentPage<TObject>
#else
public partial class FormsItem__1 : ContentPage
#endif
{
public FormsItem__1()
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "http://json.schemastore.org/dotnetcli.host",
"symbolInfo": {
"namespace": {
"shortName": "na"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$schema": "http://json.schemastore.org/vs-2017.3.host"
}
70 changes: 70 additions & 0 deletions src/FormsTemplatesCLI/FormsMvvm/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"$schema": "https://json.schemastore.org/template",
"author": "Vijay Anand E G",
"defaultName": "Forms1",
"classifications": [
"Xamarin",
"Android",
"iOS",
"macOS",
"Windows",
"MVVM",
"Xaml"
],
"identity": "VijayAnand.FormsMvvm",
"groupIdentity": "VijayAnand.FormsTemplates.Mvvm.Xaml",
"description": "An item template for Xamarin.Forms ContentPage in XAML and its ViewModel",
"name": "Xamarin.Forms ContentPage and ViewModel",
"shortName": "forms-mvvm",
"sourceName": "Forms.1",
"primaryOutputs": [
{
"path": "Forms.1Page.xaml"
},
{
"path": "Forms.1Page.xaml.cs"
},
{
"path": "Forms.1ViewModel.cs"
}
],
"tags": {
"language": "C#",
"type": "item"
},
"sources": [
{
"condition": "(SameFolder)",
"include": [
"**/*"
]
},
{
"condition": "(!SameFolder)",
"rename": {
"Forms.1Page.xaml": "Views/Forms.1Page.xaml",
"Forms.1Page.xaml.cs": "Views/Forms.1Page.xaml.cs",
"Forms.1ViewModel.cs": "ViewModels/Forms.1ViewModel.cs"
}
}
],
"symbols": {
"namespace": {
"type": "parameter",
"datatype": "text",
"description": "namespace for the generated code",
"replaces": "MyApp.Namespace"
},
"same-folder": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "false",
"description": "Option to create the artifacts in the same folder.",
"displayName": "Option to create the artifacts in the same folder"
},
"SameFolder": {
"type": "computed",
"value": "(same-folder)"
}
}
}
34 changes: 34 additions & 0 deletions src/FormsTemplatesCLI/FormsMvvm/Forms.1Page.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--#if (SameFolder)-->
<ContentPage
x:Class="MyApp.Namespace.Forms__1Page"
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:MyApp.Namespace"
xmlns:vm="clr-namespace:MyApp.Namespace"
x:DataType="vm:Forms__1ViewModel"
mc:Ignorable="d">
<!--#else-->
<ContentPage
x:Class="MyApp.Namespace.Views.Forms__1Page"
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:MyApp.Namespace"
xmlns:vm="clr-namespace:MyApp.Namespace.ViewModels"
x:DataType="vm:Forms__1ViewModel"
mc:Ignorable="d">
<!--#endif-->
<ContentPage.Content>
<Grid>
<Label
HorizontalOptions="Center"
Text="Welcome to Xamarin.Forms!!!"
TextColor="Purple"
VerticalOptions="Center" />
</Grid>
</ContentPage.Content>
</ContentPage>
23 changes: 23 additions & 0 deletions src/FormsTemplatesCLI/FormsMvvm/Forms.1Page.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

#if (!SameFolder)
using MyApp.Namespace.ViewModels;

#endif
#if SameFolder
namespace MyApp.Namespace
#else
namespace MyApp.Namespace.Views
#endif
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Forms__1Page : ContentPage
{
public Forms__1Page()
{
InitializeComponent();
BindingContext = new Forms__1ViewModel();
}
}
}
14 changes: 14 additions & 0 deletions src/FormsTemplatesCLI/FormsMvvm/Forms.1ViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#if SameFolder
namespace MyApp.Namespace
#else
namespace MyApp.Namespace.ViewModels
#endif
{
public partial class Forms__1ViewModel : BaseViewModel
{
public Forms__1ViewModel()
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "http://json.schemastore.org/dotnetcli.host",
"symbolInfo": {
"namespace": {
"shortName": "na"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$schema": "http://json.schemastore.org/vs-2017.3.host"
}
66 changes: 66 additions & 0 deletions src/FormsTemplatesCLI/FormsMvvmCS/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"$schema": "https://json.schemastore.org/template",
"author": "Vijay Anand E G",
"defaultName": "Forms1",
"classifications": [
"Xamarin",
"Android",
"iOS",
"macOS",
"Windows",
"MVVM",
"Code"
],
"identity": "VijayAnand.FormsMvvmCS",
"groupIdentity": "VijayAnand.FormsTemplates.Mvvm.Code",
"description": "An item template for Xamarin.Forms ContentPage in C# and its ViewModel",
"name": "Xamarin.Forms ContentPage and ViewModel (C#)",
"shortName": "forms-mvvm-cs",
"sourceName": "Forms.1",
"primaryOutputs": [
{
"path": "Forms.1Page.cs"
},
{
"path": "Forms.1ViewModel.cs"
}
],
"tags": {
"language": "C#",
"type": "item"
},
"sources": [
{
"condition": "(SameFolder)",
"include": [
"**/*"
]
},
{
"condition": "(!SameFolder)",
"rename": {
"Forms.1Page.cs": "Views/Forms.1Page.cs",
"Forms.1ViewModel.cs": "ViewModels/Forms.1ViewModel.cs"
}
}
],
"symbols": {
"namespace": {
"type": "parameter",
"datatype": "text",
"description": "namespace for the generated code",
"replaces": "MyApp.Namespace"
},
"same-folder": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "false",
"description": "Option to create the artifacts in the same folder.",
"displayName": "Option to create the artifacts in the same folder"
},
"SameFolder": {
"type": "computed",
"value": "(same-folder)"
}
}
}
33 changes: 33 additions & 0 deletions src/FormsTemplatesCLI/FormsMvvmCS/Forms.1Page.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Xamarin.Forms;

#if (!SameFolder)
using MyApp.Namespace.ViewModels;

#endif
#if SameFolder
namespace MyApp.Namespace
#else
namespace MyApp.Namespace.Views
#endif
{
public partial class Forms__1Page : ContentPage
{
public Forms__1Page()
{
BindingContext = new Forms__1ViewModel();
Content = new Grid()
{
Children =
{
new Label()
{
Text = "Welcome to Xamarin.Forms!!!",
TextColor = Color.Purple,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
}
}
};
}
}
}
14 changes: 14 additions & 0 deletions src/FormsTemplatesCLI/FormsMvvmCS/Forms.1ViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#if SameFolder
namespace MyApp.Namespace
#else
namespace MyApp.Namespace.ViewModels
#endif
{
public partial class Forms__1ViewModel : BaseViewModel
{
public Forms__1ViewModel()
{

}
}
}
4 changes: 2 additions & 2 deletions src/FormsTemplatesCLI/VijayAnand.FormsTemplates.csproj
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
<PackageVersion>1.0.0</PackageVersion>
<Title>Xamarin.Forms Templates</Title>
<Authors>Vijay Anand E G</Authors>
<Copyright>Copyright &#169; 2022-2023 Vijay Anand E G</Copyright>
<Copyright>Copyright &#169; 2022-2024 Vijay Anand E G</Copyright>
<Description>Project and Item templates for developing Xamarin.Forms App that runs on iOS, Android, and Windows.</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<IncludeContentInPack>true</IncludeContentInPack>
@@ -27,7 +27,7 @@
<PublishRepositoryUrl>true</PublishRepositoryUrl>
</PropertyGroup>
<ItemGroup>
<Content Include="FormsPage\**\*;FormsPageCS\**\*;FormsView\**\*;FormsViewCS\**\*;FormsShell\**\*;FormsShellCS\**\*;FormsClassLib\**\*;FormsResDict\**\*" Exclude="**\bin\**;**\obj\**"/>
<Content Include="FormsItem\**\*;FormsItemCS\**\*;FormsMvvm\**\*;FormsMvvmCS\**\*;FormsPage\**\*;FormsPageCS\**\*;FormsView\**\*;FormsViewCS\**\*;FormsShell\**\*;FormsShellCS\**\*;FormsClassLib\**\*;FormsResDict\**\*" Exclude="**\bin\**;**\obj\**"/>
<Compile Remove="**\*"/>
<None Include="overview.md" Pack="true" PackagePath="\"/>
<None Include="release-notes.txt"/>
65 changes: 64 additions & 1 deletion src/FormsTemplatesCLI/release-notes.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,70 @@
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.6.0:
What's new in ver. 1.7.0:
-------------------------
1. 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

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.

Note: Namespace resolution in both XAML and C# file is left to the user as deriving them with the template is outside its scope.

Example:

dotnet new forms-item -n ThemePopup -b xct:Popup -p:na MyApp.Views

Output: ThemePopup.xaml and ThemePopup.xaml.cs

public partial class ThemePopup : Popup {}

dotnet new forms-item -n SearchPage -b FormsPage -g SearchViewModel -p:na MyApp.Views

Output: SearchPage.xaml and SearchPage.xaml.cs

public partial class SearchPage : FormsPage<SearchViewModel> {}

2. Introduced an item template to generate Page and its ViewModel in a single command, available for both XAML and C#.

The Page will be generated in the Views folder and ViewModel will be generated in the ViewModels folder.

Can also be overridden to generate in the same folder with the -sf | --same-folder option.

The ViewModels are generated with the base class titled BaseViewModel (implementation left to the user).

Including CommunityToolkit.Mvvm, an officially supported NuGet package, would be the best fit as it makes it easy to work with the MVVM design pattern.

And it's recommended to use this MVVM template from the project root. So that output is aligned to the folder structure.

Note: Don't suffix anything to the name, it'll be included automatically.

dotnet new forms-mvvm -n Login -p:na MyApp

dotnet new forms-mvvm-cs -n Search -p:na MyApp

Output structure:

XAML:

ViewModels
LoginViewModel.cs
Views
LoginPage.xaml
LoginPage.xaml.cs

C#:

ViewModels
SearchViewModel.cs
Views
SearchPage.cs

v1.6.0:

1. Introduced an option to add a reference to Xamarin.Essentials.Interfaces NuGet package, an explicit option

2. Auto inclusion of the Type of the Item template that is created for Page, Shell, and Views

0 comments on commit d47c88e

Please sign in to comment.