Show initial category count

This commit is contained in:
TheXamlGuy
2024-06-15 18:37:02 +01:00
parent 7a811acde5
commit a1784d75b8
14 changed files with 123 additions and 136 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ public class ContentDialogHandler(IDispatcher dispatcher) :
{
public async Task Handle(NavigateEventArgs<ContentDialog> args)
{
if (args.Region is ContentDialog contentDialog)
if (args.Template is ContentDialog contentDialog)
{
contentDialog.DataContext = args.Content;
+1 -1
View File
@@ -40,7 +40,7 @@ public class FrameHandler :
await deactivated.OnDeactivated();
}
if (content is not INavigationBackStack)
if (content is not IKeepAlive)
{
if (content is IDisposable disposable)
{
+1 -1
View File
@@ -37,7 +37,7 @@ public class ComponentBuilder :
services.AddTransient<IMediator, Mediator>();
services.AddTransient<IContentFactory, ContentFactory>();
services.AddTransient<INavigationScope, NavigationScope>();
services.AddTransient<INavigation, Navigation>();
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>();
services.AddTransient<INavigationRegionProvider, NavigationRegionProvider>();
+1 -3
View File
@@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
namespace Toolkit.Foundation;
namespace Toolkit.Foundation;
public class ContentFactory(IMediator mediator,
IServiceProvider provider,
+1 -1
View File
@@ -50,7 +50,7 @@ public class DefaultHostBuilder :
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>();
services.AddTransient<INavigationRegionProvider, NavigationRegionProvider>();
services.AddScoped<INavigationScope, NavigationScope>();
services.AddScoped<INavigation, Navigation>();
services.AddSingleton(new NamedComponent("Root"));
services.AddScoped<IComponentScopeCollection, ComponentScopeCollection>(provider => new ComponentScopeCollection
+2 -1
View File
@@ -3,6 +3,7 @@ namespace Toolkit.Foundation
{
public interface IContentFactory
{
Task<object?> CreateAsync(IContentTemplateDescriptor descriptor, object[] resolvedArguments);
Task<object?> CreateAsync(IContentTemplateDescriptor descriptor,
object[] resolvedArguments);
}
}
+3
View File
@@ -0,0 +1,3 @@
namespace Toolkit.Foundation;
public interface IKeepAlive;
+7 -1
View File
@@ -2,5 +2,11 @@
public interface INavigation
{
Type Type { get; set; }
void Navigate(string route,
object? sender = null,
object? region = null,
EventHandler? navigated = null,
IDictionary<string, object>? parameters = null);
void Back(object? region);
}
@@ -1,3 +0,0 @@
namespace Toolkit.Foundation;
public interface INavigationBackStack;
-12
View File
@@ -1,12 +0,0 @@
namespace Toolkit.Foundation;
public interface INavigationScope
{
void Navigate(string route,
object? sender = null,
object? region = null,
EventHandler? navigated = null,
IDictionary<string, object>? parameters = null);
void Back(object? region);
}
+2 -2
View File
@@ -10,8 +10,8 @@ public class NavigateBackHandler(IComponentScopeProvider provider) :
if (provider.Get(args.Scope ?? "Root")
is ComponentScopeDescriptor descriptor)
{
if (descriptor?.Services?.GetService<INavigationScope>() is
INavigationScope navigationScope)
if (descriptor?.Services?.GetService<INavigation>() is
INavigation navigationScope)
{
navigationScope.Back(args.Context);
}
+4 -4
View File
@@ -8,20 +8,20 @@ public class NavigateHandler(NamedComponent scope,
{
public Task Handle(NavigateEventArgs args)
{
INavigationScope? navigationScope = null;
INavigation? navigationScope = null;
if (args.Scope is "self" || args.Scope is "new")
{
if (args.Sender is IServiceProviderRequired requireServiceProvider)
{
if (args.Scope is "self")
{
navigationScope = requireServiceProvider.Provider.GetRequiredService<INavigationScope>();
navigationScope = requireServiceProvider.Provider.GetRequiredService<INavigation>();
}
if (args.Scope is "new")
{
IServiceScope serviceScope = requireServiceProvider.Provider.CreateScope();
navigationScope = serviceScope.ServiceProvider.GetRequiredService<INavigationScope>();
navigationScope = serviceScope.ServiceProvider.GetRequiredService<INavigation>();
}
}
}
@@ -29,7 +29,7 @@ public class NavigateHandler(NamedComponent scope,
if (navigationScope is null)
{
ComponentScopeDescriptor? descriptor = componentScopeProvider.Get(args.Scope ?? scope.Name);
navigationScope = descriptor?.Services?.GetRequiredService<INavigationScope>();
navigationScope = descriptor?.Services?.GetRequiredService<INavigation>();
}
navigationScope?.Navigate(args.Route, args.Sender,
+100 -3
View File
@@ -1,7 +1,104 @@
namespace Toolkit.Foundation;
using Microsoft.Extensions.DependencyInjection;
public record Navigation :
namespace Toolkit.Foundation;
public class Navigation(IServiceProvider provider,
INavigationRegionProvider navigationRegionProvider,
IContentFactory contentFactory,
IPublisher publisher) :
INavigation
{
public required Type Type { get; set; }
public async void Navigate(string route,
object? sender = null,
object? region = null,
EventHandler? navigated = null,
IDictionary<string, object>? parameters = null)
{
if (region is null)
{
return;
}
string[] segments = route.Split('/');
int segmentCount = segments.Length;
int currentSegmentIndex = 0;
foreach (object segment in segments)
{
currentSegmentIndex++;
if (provider.GetKeyedService<IContentTemplateDescriptor>(segment)
is IContentTemplateDescriptor descriptor)
{
Dictionary<string, object>? arguments = parameters?.ToDictionary(x => x.Key, x => x.Value, StringComparer.InvariantCultureIgnoreCase) ?? [];
object[]? resolvedArguments = parameters is not null ? [.. descriptor.ContentType
.GetConstructors()
.FirstOrDefault()?
.GetParameters()
.Select(x => x?.Name is not null && arguments
.TryGetValue(x.Name, out object? argument) ? argument : default)
.Where(argument => argument is not null)] : [];
if (provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key)
is object template)
{
if (region is not null)
{
switch (region)
{
case "self":
region = template;
break;
default:
if (navigationRegionProvider.TryGet(region, out object? value))
{
region = value;
}
break;
}
}
if (region is not null)
{
object? content = await contentFactory.CreateAsync(descriptor, resolvedArguments);
if (content is not null)
{
Type navigationType = region is Type type ? type : region.GetType();
Type navigateEventType = typeof(NavigateEventArgs<>).MakeGenericType(navigationType);
if (Activator.CreateInstance(navigateEventType, [region, template, content, sender, parameters])
is object navigateEvent)
{
publisher.Publish(navigateEvent, navigationType.Name);
if (currentSegmentIndex == segmentCount)
{
navigated?.Invoke(this, EventArgs.Empty);
}
}
}
}
}
}
}
}
public void Back(object? region)
{
if (region is not null)
{
navigationRegionProvider.TryGet(region, out region);
}
if (region is not null)
{
Type navigationType = region is Type type ? type : region.GetType();
Type navigateType = typeof(NavigateBackEventArgs<>).MakeGenericType(navigationType);
if (Activator.CreateInstance(navigateType, [region]) is object navigate)
{
publisher.Publish(navigate, navigationType.Name);
}
}
}
}
-103
View File
@@ -1,103 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
namespace Toolkit.Foundation;
public class NavigationScope(IServiceProvider provider,
INavigationRegionProvider navigationRegionProvider,
IContentFactory contentFactory,
IPublisher publisher) :
INavigationScope
{
public async void Navigate(string route,
object? sender = null,
object? region = null,
EventHandler? navigated = null,
IDictionary<string, object>? parameters = null)
{
if (region is null)
{
return;
}
string[] segments = route.Split('/');
int segmentCount = segments.Length;
int currentSegmentIndex = 0;
foreach (object segment in segments)
{
currentSegmentIndex++;
if (provider.GetKeyedService<IContentTemplateDescriptor>(segment)
is IContentTemplateDescriptor descriptor)
{
Dictionary<string, object>? arguments = parameters?.ToDictionary(x => x.Key, x => x.Value, StringComparer.InvariantCultureIgnoreCase) ?? [];
object[]? resolvedArguments = parameters is not null ? [.. descriptor.ContentType
.GetConstructors()
.FirstOrDefault()?
.GetParameters()
.Select(x => x?.Name is not null && arguments
.TryGetValue(x.Name, out object? argument) ? argument : default)
.Where(argument => argument is not null)] : [];
if (provider.GetRequiredKeyedService(descriptor.TemplateType, descriptor.Key)
is object template)
{
if (region is not null)
{
switch (region)
{
case "self":
region = template;
break;
default:
if (navigationRegionProvider.TryGet(region, out object? value))
{
region = value;
}
break;
}
}
if (region is not null)
{
object? content = await contentFactory.CreateAsync(descriptor, resolvedArguments);
if (content is not null)
{
Type navigationType = region is Type type ? type : region.GetType();
Type navigateEventType = typeof(NavigateEventArgs<>).MakeGenericType(navigationType);
if (Activator.CreateInstance(navigateEventType, [region, template, content, sender, parameters])
is object navigateEvent)
{
publisher.Publish(navigateEvent, navigationType.Name);
if (currentSegmentIndex == segmentCount)
{
navigated?.Invoke(this, EventArgs.Empty);
}
}
}
}
}
}
}
}
public void Back(object? region)
{
if (region is not null)
{
navigationRegionProvider.TryGet(region, out region);
}
if (region is not null)
{
Type navigationType = region is Type type ? type : region.GetType();
Type navigateType = typeof(NavigateBackEventArgs<>).MakeGenericType(navigationType);
if (Activator.CreateInstance(navigateType, [region]) is object navigate)
{
publisher.Publish(navigate, navigationType.Name);
}
}
}
}