Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .github/workflows/dotnet-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
- 'README.md'

jobs:
build:
build-avaloniaui:
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand All @@ -30,3 +30,17 @@ jobs:
- name: Build
run: dotnet build --configuration Release --no-restore
working-directory: src/Lemon.ModuleNavigation.Sample.Desktop
build-wpf:
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
- name: Setup .NET 8
uses: actions/setup-dotnet@v3
with:
dotnet-version: 8.0.x
- name: Install dependencies
run: dotnet restore
working-directory: src/Lemon.ModuleNavigation.WpfSample
- name: Build WPF Sample
run: dotnet build --configuration Release --no-restore
working-directory: src/Lemon.ModuleNavigation.WpfSample
69 changes: 61 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,79 @@ on:
branches: [ "action/release" ]

jobs:
nuget:
nuget-abstraction:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.1.1

- name: Build the Project
run: dotnet build ./src/Lemon.ModuleNavigation.Avaloniaui --configuration Release
run: dotnet build ./src/Lemon.ModuleNavigation --configuration Release

- name: Pack Nuget
run: dotnet pack ./src/Lemon.ModuleNavigation -o ./nugets
run: dotnet pack ./src/Lemon.ModuleNavigation --configuration Release --no-build -o ./nugets

- name: Publish NuGet package
run: |
if [ -n "$(find ./nugets -name '*.nupkg')" ]; then
dotnet nuget push "./nugets/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
fi

- name: Upload a Build Artifact
uses: actions/upload-artifact@v4.3.1
with:
name: nugets-abstraction
path: ./nugets

nuget-avaloniaui:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.1.1

- name: Build the Project
run: dotnet build ./src/Lemon.ModuleNavigation.Avaloniaui --configuration Release

- name: Pack Nuget
run: dotnet pack ./src/Lemon.ModuleNavigation.Avaloniaui -o ./nugets
run: dotnet pack ./src/Lemon.ModuleNavigation.Avaloniaui --configuration Release --no-build -o ./nugets

- name: Publish NuGet package
run: dotnet nuget push "./nugets/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
run: |
if [ -n "$(find ./nugets -name '*.nupkg')" ]; then
dotnet nuget push "./nugets/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
fi

- name: Upload a Build Artifact
uses: actions/upload-artifact@v4.3.1
with:
name: nugets
name: nugets-avaloniaui
path: ./nugets

nuget-wpf:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4.1.1

- name: Setup .NET 8
uses: actions/setup-dotnet@v3
with:
dotnet-version: 8.0.x

- name: Build the WPF Project
run: dotnet build ./src/Lemon.ModuleNavigation.Wpf --configuration Release

- name: Pack WPF Nuget
run: dotnet pack ./src/Lemon.ModuleNavigation.Wpf --configuration Release --no-build -o ./nugets

- name: Publish WPF NuGet package
run: |
if (Test-Path "./nugets/*.nupkg") {
dotnet nuget push "./nugets/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
}

- name: Upload WPF NuGet Artifact
uses: actions/upload-artifact@v4.3.1
with:
name: nugets-wpf
path: ./nugets
5 changes: 2 additions & 3 deletions src/Lemon.ModuleNavigation.Avaloniaui/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Avalonia.Metadata;

[assembly: XmlnsPrefix("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "l")]
[assembly: XmlnsPrefix("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "lm")]
[assembly: XmlnsDefinition("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "Lemon.ModuleNavigation")]
[assembly: XmlnsDefinition("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "Lemon.ModuleNavigation.Avaloniaui")]
[assembly: XmlnsDefinition("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "Lemon.ModuleNavigation.Avaloniaui.Core")]
[assembly: XmlnsDefinition("https://github.com/NeverMorewd/Lemon.ModuleNavigation", "Lemon.ModuleNavigation.Avaloniaui")]
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Lemon.ModuleNavigation.Abstracts;
using Lemon.ModuleNavigation.Core;
using Lemon.ModuleNavigation.Abstractions;
using System.Diagnostics.CodeAnalysis;

namespace Lemon.ModuleNavigation.Avaloniaui.Core;
namespace Lemon.ModuleNavigation.Avaloniaui;

[Obsolete($"Use Module instead, they are equivalent.")]
public abstract class AvaModule<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TView,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TViewModel>
: Module<TView, TViewModel>
Expand Down
64 changes: 64 additions & 0 deletions src/Lemon.ModuleNavigation.Avaloniaui/AvaloniauiRegion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Lemon.ModuleNavigation.Abstractions;
using Lemon.ModuleNavigation.Core;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent;
using System.Collections.ObjectModel;

namespace Lemon.ModuleNavigation.Avaloniaui;

public abstract class AvaloniauiRegion : IRegion
{
private readonly ConcurrentDictionary<string, IView> _viewCache = new();
private readonly ConcurrentItem<(IView View, INavigationAware NavigationAware)> _current = new();

public AvaloniauiRegion()
{
RegionTemplate = CreateRegionDataTemplate();
}

public abstract string Name { get; }
public abstract ObservableCollection<NavigationContext> Contexts { get; }

public IDataTemplate? RegionTemplate { get; set; }

public abstract void Activate(NavigationContext target);
public abstract void DeActivate(NavigationContext target);

private IDataTemplate CreateRegionDataTemplate()
{
return new FuncDataTemplate<NavigationContext>((context, np) =>
{
if (context == null)
return null;

bool needNewView = context.RequestNew ||
!_viewCache.TryGetValue(context.TargetViewName, out IView? view);

if (needNewView)
{
view = context.ServiceProvider.GetRequiredKeyedService<IView>(context.TargetViewName);
var navigationAware = context.ServiceProvider.GetRequiredKeyedService<INavigationAware>(context.TargetViewName);

if (_current.TryTakeData(out var previousData))
{
previousData.NavigationAware.OnNavigatedFrom(context);
}
if (!navigationAware.IsNavigationTarget(context))
return null;

view.DataContext = navigationAware;
navigationAware.OnNavigatedTo(context);
_current.SetData((view, navigationAware));
_viewCache.TryAdd(context.TargetViewName, view);
}
else
{
view = _viewCache[context.TargetViewName];
}

return view as Control;
});
}
}
64 changes: 64 additions & 0 deletions src/Lemon.ModuleNavigation.Avaloniaui/ContentRegion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Avalonia.Controls;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace Lemon.ModuleNavigation.Avaloniaui;

public class ContentRegion : AvaloniauiRegion
{
private readonly ContentControl _contentControl;
public ContentRegion(ContentControl contentControl, string name) : base()
{
_contentControl = contentControl;
_contentControl.ContentTemplate = RegionTemplate;
Contexts = [];
Contexts.CollectionChanged += ViewContents_CollectionChanged;
Name = name;
}

public override string Name
{
get;
}
public object? Content
{
get => _contentControl.Content;
set
{
_contentControl.Content = value;
}
}
public override ObservableCollection<NavigationContext> Contexts
{
get;
}

public override void Activate(NavigationContext target)
{
if(Content is NavigationContext current)
{
if (target.TargetViewName == current.TargetViewName
&& !target.RequestNew)
{
return;
}
}
Content = target;
}

public override void DeActivate(NavigationContext target)
{
Content = null;
}
private void ViewContents_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
//
}
if (e.Action == NotifyCollectionChangedAction.Remove)
{
//
}
}
}
Loading
Loading