Skip to content

Commit

Permalink
Merge pull request #12 from sylac/feature/add-on-navigation-methods
Browse files Browse the repository at this point in the history
add on navigation methods
  • Loading branch information
sylac authored Jan 10, 2025
2 parents b377534 + 916e6d3 commit 8b147cb
Show file tree
Hide file tree
Showing 32 changed files with 188 additions and 152 deletions.
34 changes: 34 additions & 0 deletions Sylac.Mvvm.Core/Abstraction/IViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Sylac.Mvvm.Abstraction;

public interface IViewModel
{
/// <summary>
/// Called when the navigation to the view model is initiated.
/// </summary>
void OnNavigatingTo();

/// <summary>
/// Called when the navigation from the view model is initiated.
/// </summary>
void OnNavigatingFrom();

/// <summary>
/// Called when the navigation to the view model is completed.
/// </summary>
void OnNavigatedTo();

/// <summary>
/// Called when the navigation from the view model is completed.
/// </summary>
void OnNavigatedFrom();
}

public interface IViewModel<out TParam> : IViewModel
where TParam : IViewModelParameters
{
/// <summary>
/// Initializes the view model with the provided parameters.
/// </summary>
/// <param name="parameter"> The parameters to initialize the view model with. </param>
void Initialize(IViewModelParameters parameter);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
namespace Sylac.Mvvm;
namespace Sylac.Mvvm.Abstraction;

public interface IViewModelParameters;
15 changes: 0 additions & 15 deletions Sylac.Mvvm.Core/IViewModel.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reactive;
using Sylac.Mvvm.Abstraction;
using System.Reactive;

namespace Sylac.Mvvm.Navigation.Abstractions;

Expand Down
13 changes: 7 additions & 6 deletions Sylac.Mvvm.Core/Navigation/ConnectWithViewModelAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
namespace Sylac.Mvvm.Navigation
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class ConnectWithViewModelAttribute<TViewModel, TParams>() : Attribute
using Sylac.Mvvm.Abstraction;

namespace Sylac.Mvvm.Navigation;

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class ConnectWithViewModelAttribute<TViewModel, TParams>() : Attribute
where TViewModel : IViewModel<TParams>
where TParams : IViewModelParameters
{
}
{
}
36 changes: 11 additions & 25 deletions Sylac.Mvvm.Core/Navigation/NavigationService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using Sylac.Mvvm.Navigation.Abstractions;
using Sylac.Mvvm.Abstraction;
using Sylac.Mvvm.Navigation.Abstractions;
using System.Reactive;
using System.Reactive.Linq;

namespace Sylac.Mvvm.Navigation;

public class NavigationService(IPlatformNavigation platformNavigation) : INavigationService
public sealed class NavigationService(IPlatformNavigation platformNavigation) : INavigationService
{
private readonly IPlatformNavigation _platformNavigation = platformNavigation;
internal static Dictionary<Type, (string Page, Type ParametersType)> ViewModelsRegistry { get; } = [];
Expand Down Expand Up @@ -41,33 +42,18 @@ public IObservable<Unit> NavigateTo<TViewModel, TParams>(TParams parameters)
where TParams : IViewModelParameters
{
return Observable.Return(ViewModelsRegistry.GetValueOrDefault(typeof(TViewModel)))
.Where(result =>
result.Page != default &&
result.ParametersType != default)
.Where(result => result != default)
.SelectMany(result =>
{
// is type check needed? Is it possible to pass a different type?
if (parameters.GetType() != result.ParametersType)
{
return Observable.Throw<Unit>(new ArgumentException("Invalid parameters type"));
}

return _platformNavigation.GoTo(result.Page, new Dictionary<string, object>() { { INavigationablePage.ParametersKey, parameters } });
})
parameters.GetType() != result.ParametersType
? Observable.Throw<Unit>(new ArgumentException("Invalid parameters type"))
: _platformNavigation.GoTo(result.Page, new Dictionary<string, object>() { { INavigationablePage.ParametersKey, parameters } }))
.IsEmpty()
.SelectMany(isEmpty =>
{
if (isEmpty)
{
return Observable.Throw<Unit>(new ArgumentException("Error navigating to page"));
}
return Observable.Return(Unit.Default);
});
.SelectMany(isEmpty => isEmpty
? Observable.Throw<Unit>(new ArgumentException("Error navigating to page"))
: Observable.Return(Unit.Default));
}

public IObservable<Unit> NavigateBack()
{
return _platformNavigation.GoTo("..");
}
public IObservable<Unit> NavigateBack() => _platformNavigation.GoTo("..");
}

8 changes: 4 additions & 4 deletions Sylac.Mvvm.Core/RegisterMvvmPageExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Sylac.Mvvm.Abstraction;
using Sylac.Mvvm.Navigation.Abstractions;

namespace Sylac.Mvvm;
Expand All @@ -14,10 +15,9 @@ public static IServiceCollection RegisterMvvmPage<TPage, TViewModel>(
{
services.Add(new(typeof(TPage), null, typeof(TPage), pageLifetime));
services.Add(new(typeof(TViewModel), null, typeof(TViewModel), viewModelLifetime));

using var serviceProvider = services.BuildServiceProvider();
var navigetionService = serviceProvider.GetRequiredService<INavigationService>();
navigetionService.RegisterNavigationView<TPage, TViewModel>();
services.BuildServiceProvider()
.GetRequiredService<INavigationService>()
.RegisterNavigationView<TPage, TViewModel>();

return services;
}
Expand Down
14 changes: 10 additions & 4 deletions Sylac.Mvvm.Core/Sylac.Mvvm.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>

<IsPackable>true</IsPackable>
<PackageId>Sylac.Mvvm.Core</PackageId>
<RootNamespace>Sylac.Mvvm</RootNamespace>
<Version>0.2.0</Version>
<Version>0.3.0</Version>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Authors>Sylwester Łach</Authors>
<RepositoryUrl>https://github.com/sylac/Sylac.Mvvm</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageTags>nuget, packaging, generator, example</PackageTags>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="System.Reactive" Version="6.0.1" />
</ItemGroup>


<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="\"/>
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="Sylac.Mvvm.UnitTests" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Sylac.Mvvm.Example/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ insert_final_newline = false

# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
dotnet_sort_system_directives_first = true
file_header_template = unset

# this. and Me. preferences
Expand Down
5 changes: 4 additions & 1 deletion Sylac.Mvvm.Example/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ public partial class App : Application
public App()
{
InitializeComponent();
}

MainPage = new AppShell();
protected override Window CreateWindow(IActivationState? activationState)
{
return new(new AppShell());
}
}
}
51 changes: 25 additions & 26 deletions Sylac.Mvvm.Example/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,37 @@
using Sylac.Mvvm.Example.ViewModels;
using Sylac.Mvvm.Maui;

namespace Sylac.Mvvm.Example
namespace Sylac.Mvvm.Example;

public static class MauiProgram
{
public static class MauiProgram
public static MauiApp CreateMauiApp()
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});

builder.Services
.UseSylacMaui()
.RegisterViews();
builder.Services
.UseSylacMaui()
.RegisterViews();

#if DEBUG
builder.Logging.AddDebug();
builder.Logging.AddDebug();
#endif

return builder.Build();
}
static IServiceCollection RegisterViews(this IServiceCollection services)
{
return services
.RegisterMvvmPage<MainPage, MainPageViewModel>()
.RegisterMvvmPage<ShellTabPage, ShellTabPageViewModel>()
.RegisterMvvmPage<ExamplePage, ExamplePageViewModel>()
.RegisterMvvmPage<SecondExamplePage, SecondExamplePageViewModel>();
}
return builder.Build();
}
static IServiceCollection RegisterViews(this IServiceCollection services)
{
return services
.RegisterMvvmPage<MainPage, MainPageViewModel>()
.RegisterMvvmPage<ShellTabPage, ShellTabPageViewModel>()
.RegisterMvvmPage<ExamplePage, ExamplePageViewModel>()
.RegisterMvvmPage<SecondExamplePage, SecondExamplePageViewModel>();
}
}
4 changes: 2 additions & 2 deletions Sylac.Mvvm.Example/Pages/ExamplePage.xaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<sylac:NavigationablePage x:Class="Sylac.Mvvm.Example.Pages.ExamplePage"
<sylac:NavigablePage x:Class="Sylac.Mvvm.Example.Pages.ExamplePage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sylac="clr-namespace:Sylac.Mvvm.Maui.Controls;assembly=Sylac.Mvvm.Maui"
Expand All @@ -10,4 +10,4 @@
<Label HorizontalOptions="Center" Text="{Binding EnteredText}" VerticalOptions="Center" />
<Button Command="{Binding ShowSecondExamplePageCommand}" Text="Show second example page" />
</VerticalStackLayout>
</sylac:NavigationablePage>
</sylac:NavigablePage>
2 changes: 1 addition & 1 deletion Sylac.Mvvm.Example/Pages/ExamplePage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Sylac.Mvvm.Example.Pages;

[ConnectWithViewModel<ExamplePageViewModel, ExamplePageViewModelParameters>]
public partial class ExamplePage : NavigationablePage
public partial class ExamplePage : NavigablePage
{
public ExamplePage(ExamplePageViewModel examplePageViewModel)
: base(examplePageViewModel)
Expand Down
4 changes: 2 additions & 2 deletions Sylac.Mvvm.Example/Pages/MainPage.xaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<sylac:NavigationablePage
<sylac:NavigablePage
x:Class="Sylac.Mvvm.Example.Pages.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
Expand Down Expand Up @@ -32,4 +32,4 @@
</VerticalStackLayout>
</ScrollView>

</sylac:NavigationablePage>
</sylac:NavigablePage>
2 changes: 1 addition & 1 deletion Sylac.Mvvm.Example/Pages/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Sylac.Mvvm.Example.Pages;

public partial class MainPage : NavigationablePage
public partial class MainPage : NavigablePage
{
public MainPage(MainPageViewModel mainPageViewModel)
: base(mainPageViewModel)
Expand Down
4 changes: 2 additions & 2 deletions Sylac.Mvvm.Example/Pages/SecondExamplePage.xaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<sylac:NavigationablePage x:Class="Sylac.Mvvm.Example.Pages.SecondExamplePage"
<sylac:NavigablePage x:Class="Sylac.Mvvm.Example.Pages.SecondExamplePage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:sylac="clr-namespace:Sylac.Mvvm.Maui.Controls;assembly=Sylac.Mvvm.Maui"
Expand All @@ -8,4 +8,4 @@
<VerticalStackLayout>
<Label HorizontalOptions="Center" Text="Welcome to .NET MAUI!" VerticalOptions="Center" />
</VerticalStackLayout>
</sylac:NavigationablePage>
</sylac:NavigablePage>
2 changes: 1 addition & 1 deletion Sylac.Mvvm.Example/Pages/SecondExamplePage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Sylac.Mvvm.Example.Pages;

public partial class SecondExamplePage : NavigationablePage
public partial class SecondExamplePage : NavigablePage
{
public SecondExamplePage(SecondExamplePageViewModel pageViewModel)
: base(pageViewModel)
Expand Down
4 changes: 2 additions & 2 deletions Sylac.Mvvm.Example/Pages/ShellTabPage.xaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<sylac:NavigationablePage
<sylac:NavigablePage
x:Class="Sylac.Mvvm.Example.Pages.ShellTabPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
Expand All @@ -11,4 +11,4 @@
Text="Welcome to .NET MAUI!"
VerticalOptions="Center" />
</VerticalStackLayout>
</sylac:NavigationablePage>
</sylac:NavigablePage>
2 changes: 1 addition & 1 deletion Sylac.Mvvm.Example/Pages/ShellTabPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Sylac.Mvvm.Example.Pages;

public partial class ShellTabPage : NavigationablePage
public partial class ShellTabPage : NavigablePage
{
public ShellTabPage(ShellTabPageViewModel pageViewModel)
: base(pageViewModel)
Expand Down
10 changes: 5 additions & 5 deletions Sylac.Mvvm.Example/Sylac.Mvvm.Example.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>Sylac.Mvvm.Example</RootNamespace>
<UseMaui>true</UseMaui>
Expand Down Expand Up @@ -48,9 +48,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="8.0.92" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.92" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.1" />
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.22" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.22" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" />
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
<PackageReference Include="ReactiveUI.Maui" Version="20.1.63" />
</ItemGroup>
Expand Down
Loading

0 comments on commit 8b147cb

Please sign in to comment.