Skip to content

Commit

Permalink
Merge pull request #256 from FroggieFrog/option-to-use-mvvm-toolkit
Browse files Browse the repository at this point in the history
Option to use `CommunityToolkit.Mvvm` for template `Avalonia.App.CrossPlatform`
  • Loading branch information
maxkatz6 authored Jul 22, 2024
2 parents 64d61dc + a1990ce commit 57b7ad7
Show file tree
Hide file tree
Showing 24 changed files with 219 additions and 20 deletions.
8 changes: 8 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ Available parameters:

*By default*: true

``-m, --mvvm``

*Description*: MVVM toolkit to use in the template.

*Options*: **ReactiveUI**, **CommunityToolkit**

*By default*: ReactiveUI

``-av, --avalonia-version``

*Description*: The target version of Avalonia NuGet packages.
Expand Down
5 changes: 4 additions & 1 deletion templates/csharp/xplat/.template.config/dotnetcli.host.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
"UseCompiledBindings": {
"longName": "compiled-bindings"
},
"MVVMToolkit": {
"longName": "mvvm"
},
"RemoveViewLocator": {
"longName": "remove-view-locator"
}
},
"usageExamples": [
""
"--mvvm communitytoolkit"
]
}
7 changes: 7 additions & 0 deletions templates/csharp/xplat/.template.config/ide.host.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
},
"isVisible": true
},
{
"id": "MVVMToolkit",
"name": {
"text": "MVVM Toolkit"
},
"isVisible": true
},
{
"id": "UseCompiledBindings",
"name": {
Expand Down
24 changes: 24 additions & 0 deletions templates/csharp/xplat/.template.config/template.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,30 @@
"replaces": "FrameworkParameter",
"defaultValue": "net8.0"
},
"MVVMToolkit": {
"type": "parameter",
"description": "MVVM toolkit to use in the template.",
"datatype": "choice",
"choices": [
{
"choice": "ReactiveUI",
"description": "Choose ReactiveUI as MVVM toolkit in the template."
},
{
"choice": "CommunityToolkit",
"description": "Choose CommunityToolkit as MVVM toolkit in the template."
}
],
"defaultValue": "ReactiveUI"
},
"ReactiveUIToolkitChosen": {
"type": "computed",
"value": "(MVVMToolkit == \"ReactiveUI\")"
},
"CommunityToolkitChosen": {
"type": "computed",
"value": "(MVVMToolkit == \"CommunityToolkit\")"
},
"AvaloniaVersion": {
"type": "parameter",
"description": "The target version of Avalonia NuGet packages.",
Expand Down
6 changes: 6 additions & 0 deletions templates/csharp/xplat/AvaloniaTest.Android/MainActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using Android.Content.PM;
using Avalonia;
using Avalonia.Android;
#if (ReactiveUIToolkitChosen)
using Avalonia.ReactiveUI;
#endif

namespace AvaloniaTest.Android;

Expand All @@ -17,7 +19,11 @@ public class MainActivity : AvaloniaMainActivity<App>
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{
return base.CustomizeAppBuilder(builder)
#if (CommunityToolkitChosen)
.WithInterFont();
#else
.WithInterFont()
.UseReactiveUI();
#endif
}
}
4 changes: 4 additions & 0 deletions templates/csharp/xplat/AvaloniaTest.Browser/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Browser;
#if (ReactiveUIToolkitChosen)
using Avalonia.ReactiveUI;
#endif
using AvaloniaTest;

[assembly: SupportedOSPlatform("browser")]
Expand All @@ -11,7 +13,9 @@ internal sealed partial class Program
{
private static Task Main(string[] args) => BuildAvaloniaApp()
.WithInterFont()
#if (ReactiveUIToolkitChosen)
.UseReactiveUI()
#endif
.StartBrowserAppAsync("out");

public static AppBuilder BuildAvaloniaApp()
Expand Down
8 changes: 6 additions & 2 deletions templates/csharp/xplat/AvaloniaTest.Desktop/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using Avalonia;
#if (ReactiveUIToolkitChosen)
using Avalonia.ReactiveUI;
#endif

namespace AvaloniaTest.Desktop;

Expand All @@ -18,6 +20,8 @@ public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace()
.UseReactiveUI();
#if (ReactiveUIToolkitChosen)
.UseReactiveUI()
#endif
.LogToTrace();
}
6 changes: 6 additions & 0 deletions templates/csharp/xplat/AvaloniaTest.iOS/AppDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using Avalonia.Controls;
using Avalonia.iOS;
using Avalonia.Media;
#if (ReactiveUIToolkitChosen)
using Avalonia.ReactiveUI;
#endif

namespace AvaloniaTest.iOS;

Expand All @@ -19,7 +21,11 @@ public partial class AppDelegate : AvaloniaAppDelegate<App>
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{
return base.CustomizeAppBuilder(builder)
#if (CommunityToolkitChosen)
.WithInterFont();
#else
.WithInterFont()
.UseReactiveUI();
#endif
}
}
9 changes: 9 additions & 0 deletions templates/csharp/xplat/AvaloniaTest/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
#if (CommunityToolkitChosen)
using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins;
#endif
using Avalonia.Markup.Xaml;
using AvaloniaTest.ViewModels;
using AvaloniaTest.Views;
Expand All @@ -17,6 +21,11 @@ public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
#if (CommunityToolkitChosen)
// Line below is needed to remove Avalonia data validation.
// Without this line you will get duplicate validations from both Avalonia and CT
BindingPlugins.DataValidators.RemoveAt(0);
#endif
desktop.MainWindow = new MainWindow
{
DataContext = new MainViewModel()
Expand Down
8 changes: 6 additions & 2 deletions templates/csharp/xplat/AvaloniaTest/AvaloniaTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
<ItemGroup>
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="$(AvaloniaVersion)" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
<!--#if (ReactiveUIToolkitChosen) -->
<PackageReference Include="Avalonia.ReactiveUI" Version="$(AvaloniaVersion)" />
<!--#elif (CommunityToolkitChosen)-->
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.1" />
<!--#endif -->
</ItemGroup>
</Project>
15 changes: 14 additions & 1 deletion templates/csharp/xplat/AvaloniaTest/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
namespace AvaloniaTest.ViewModels;
#if (CommunityToolkitChosen)
using CommunityToolkit.Mvvm.ComponentModel;
#endif

namespace AvaloniaTest.ViewModels;

#if (CommunityToolkitChosen)
public partial class MainViewModel : ViewModelBase
#else
public class MainViewModel : ViewModelBase
#endif
{
#if (CommunityToolkitChosen)
[ObservableProperty]
private string _greeting = "Welcome to Avalonia!";
#else
#pragma warning disable CA1822 // Mark members as static
public string Greeting => "Welcome to Avalonia!";
#pragma warning restore CA1822 // Mark members as static
#endif
}
12 changes: 10 additions & 2 deletions templates/csharp/xplat/AvaloniaTest/ViewModels/ViewModelBase.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
using ReactiveUI;
#if (CommunityToolkitChosen)
using CommunityToolkit.Mvvm.ComponentModel;
#elif (ReactiveUIToolkitChosen)
using ReactiveUI;
#endif

namespace AvaloniaTest.ViewModels;

public class ViewModelBase : ReactiveObject
#if (CommunityToolkitChosen)
public abstract class ViewModelBase : ObservableObject
#elif (ReactiveUIToolkitChosen)
public abstract class ViewModelBase : ReactiveObject
#endif
{
}
1 change: 1 addition & 0 deletions templates/fsharp/app-mvvm/ViewModels/ViewModelBase.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ open CommunityToolkit.Mvvm.ComponentModel
open ReactiveUI
#endif

[<AbstractClass>]
type ViewModelBase() =
#if (CommunityToolkitChosen)
inherit ObservableObject()
Expand Down
5 changes: 4 additions & 1 deletion templates/fsharp/xplat/.template.config/dotnetcli.host.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
"UseCompiledBindings": {
"longName": "compiled-bindings"
},
"MVVMToolkit": {
"longName": "mvvm"
},
"RemoveViewLocator": {
"longName": "remove-view-locator"
}
},
"usageExamples": [
""
"--mvvm communitytoolkit"
]
}
7 changes: 7 additions & 0 deletions templates/fsharp/xplat/.template.config/ide.host.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
},
"isVisible": true
},
{
"id": "MVVMToolkit",
"name": {
"text": "MVVM Toolkit"
},
"isVisible": true
},
{
"id": "UseCompiledBindings",
"name": {
Expand Down
24 changes: 24 additions & 0 deletions templates/fsharp/xplat/.template.config/template.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,30 @@
"replaces": "FrameworkParameter",
"defaultValue": "net8.0"
},
"MVVMToolkit": {
"type": "parameter",
"description": "MVVM toolkit to use in the template.",
"datatype": "choice",
"choices": [
{
"choice": "ReactiveUI",
"description": "Choose ReactiveUI as MVVM toolkit in the template."
},
{
"choice": "CommunityToolkit",
"description": "Choose CommunityToolkit as MVVM toolkit in the template."
}
],
"defaultValue": "ReactiveUI"
},
"ReactiveUIToolkitChosen": {
"type": "computed",
"value": "(MVVMToolkit == \"ReactiveUI\")"
},
"CommunityToolkitChosen": {
"type": "computed",
"value": "(MVVMToolkit == \"CommunityToolkit\")"
},
"AvaloniaVersion": {
"type": "parameter",
"description": "The target version of Avalonia NuGet packages.",
Expand Down
4 changes: 4 additions & 0 deletions templates/fsharp/xplat/AvaloniaTest.Android/Activities.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ namespace AvaloniaTest.Android
open Android.App
open Android.Content.PM
open Avalonia
#if (ReactiveUIToolkitChosen)
open Avalonia.ReactiveUI
#endif
open Avalonia.Android
open AvaloniaTest

Expand All @@ -19,4 +21,6 @@ type MainActivity() =
override _.CustomizeAppBuilder(builder) =
base.CustomizeAppBuilder(builder)
.WithInterFont()
#if (ReactiveUIToolkitChosen)
.UseReactiveUI()
#endif
5 changes: 4 additions & 1 deletion templates/fsharp/xplat/AvaloniaTest.Browser/Program.fs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
open System.Runtime.Versioning
open Avalonia
open Avalonia.Browser
#if (ReactiveUIToolkitChosen)
open Avalonia.ReactiveUI

#endif
open AvaloniaTest

module Program =
Expand All @@ -19,7 +20,9 @@ module Program =
task {
do! (buildAvaloniaApp()
.WithInterFont()
#if (ReactiveUIToolkitChosen)
.UseReactiveUI()
#endif
.StartBrowserAppAsync("out"))
}
|> ignore
Expand Down
4 changes: 4 additions & 0 deletions templates/fsharp/xplat/AvaloniaTest.Desktop/Program.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
namespace AvaloniaTest.Desktop
open System
open Avalonia
#if (ReactiveUIToolkitChosen)
open Avalonia.ReactiveUI
#endif
open AvaloniaTest

module Program =
Expand All @@ -13,7 +15,9 @@ module Program =
.UsePlatformDetect()
.WithInterFont()
.LogToTrace(areas = Array.empty)
#if (ReactiveUIToolkitChosen)
.UseReactiveUI()
#endif

[<EntryPoint; STAThread>]
let main argv =
Expand Down
6 changes: 5 additions & 1 deletion templates/fsharp/xplat/AvaloniaTest.iOS/AppDelegate.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ namespace AvaloniaTest.iOS
open Foundation
open Avalonia
open Avalonia.iOS
#if (ReactiveUIToolkitChosen)
open Avalonia.ReactiveUI
#endif

// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
Expand All @@ -13,4 +15,6 @@ type [<Register("AppDelegate")>] AppDelegate() =
override _.CustomizeAppBuilder(builder) =
base.CustomizeAppBuilder(builder)
.WithInterFont()
.UseReactiveUI()
#if (ReactiveUIToolkitChosen)
.UseReactiveUI()
#endif
Loading

0 comments on commit 57b7ad7

Please sign in to comment.