Improvement to navigation regions

This commit is contained in:
TheXamlGuy
2024-05-09 22:37:36 +01:00
parent 711353c8e9
commit 54d2b5374d
31 changed files with 173 additions and 184 deletions
@@ -5,7 +5,7 @@ using Toolkit.Foundation;
namespace Toolkit.Avalonia;
public class ClassicDesktopStyleApplicationHandler(INavigationContext navigationContext) :
public class ClassicDesktopStyleApplicationHandler :
INavigateHandler<IClassicDesktopStyleApplicationLifetime>
{
public Task Handle(Navigate<IClassicDesktopStyleApplicationLifetime> args,
@@ -18,8 +18,6 @@ public class ClassicDesktopStyleApplicationHandler(INavigationContext navigation
{
lifeTime.MainWindow = window;
window.DataContext = args.Content;
navigationContext.Set(window);
}
}
+1 -3
View File
@@ -4,7 +4,7 @@ using Toolkit.Foundation;
namespace Toolkit.Avalonia;
public class ContentControlHandler(INavigationContext navigationContext) :
public class ContentControlHandler :
INavigateHandler<ContentControl>
{
public async Task Handle(Navigate<ContentControl> args,
@@ -51,8 +51,6 @@ public class ContentControlHandler(INavigationContext navigationContext) :
control.DataContext = args.Content;
contentControl.Content = control;
navigationContext.Set(control);
await taskCompletionSource.Task;
}
}
+2 -2
View File
@@ -17,7 +17,7 @@ public class ContentTemplate :
if (observableViewModel.Provider is IServiceProvider provider)
{
IContentTemplateDescriptorProvider? contentTemplateProvider = provider.GetService<IContentTemplateDescriptorProvider>();
INavigationContext? viewModelContentBinder = provider.GetService<INavigationContext>();
INavigationRegion? viewModelContentBinder = provider.GetService<INavigationRegion>();
if (contentTemplateProvider?.Get(item.GetType().Name) is IContentTemplateDescriptor descriptor)
{
@@ -55,7 +55,7 @@ public class ContentTemplate :
control.Loaded += HandleLoaded;
control.Unloaded += HandleUnloaded;
viewModelContentBinder?.Set(control);
//viewModelContentBinder?.Register(control);
return control;
}
+1 -56
View File
@@ -8,7 +8,7 @@ using Toolkit.UI.Controls.Avalonia;
namespace Toolkit.Avalonia;
public class FrameHandler(INavigationContext navigationContext) :
public class FrameHandler :
INavigateHandler<Frame>,
INavigateBackHandler<Frame>
{
@@ -45,32 +45,6 @@ public class FrameHandler(INavigationContext navigationContext) :
{
await deactivating.Deactivating();
}
Type contentType = content.GetType();
if (contentType.GetInterfaces() is Type[] contracts)
{
foreach (Type contract in contracts)
{
if (contract.Name == typeof(IDeactivating<>).Name &&
contract.GetGenericArguments() is { Length: 1 } arguments)
{
if (contentType.GetMethods().FirstOrDefault(x =>
x.Name == "Deactivating" && x.ReturnType == typeof(Task<>)
.MakeGenericType(arguments[0]))
is MethodInfo methodInfo)
{
if (methodInfo.GetCustomAttribute<NavigationContextAttribute>()
is NavigationContextAttribute attribute)
{
if (await methodInfo.InvokeAsync<object?>(content) is object result)
{
results.Add(attribute.Name, result);
}
}
}
}
}
}
}
}
}
@@ -100,33 +74,6 @@ public class FrameHandler(INavigationContext navigationContext) :
{
await deactivated.Deactivated();
}
Type contentType = content.GetType();
if (contentType.GetInterfaces() is Type[] contracts)
{
foreach (Type contract in contracts)
{
if (contract.Name == typeof(IActivated<>).Name &&
contract.GetGenericArguments() is { Length: 1 } arguments)
{
if (contentType.GetMethods().FirstOrDefault(x =>
x.Name == "NavigatedToAsync" &&
x.GetCustomAttribute<NavigationContextAttribute>()
is NavigationContextAttribute attribute && results.ContainsKey(attribute.Name))
is MethodInfo methodInfo)
{
if (methodInfo.GetCustomAttribute<NavigationContextAttribute>()
is NavigationContextAttribute attribute)
{
if (results.TryGetValue(attribute.Name, out object? value))
{
await methodInfo.InvokeAsync(content, value);
}
}
}
}
}
}
}
}
@@ -181,8 +128,6 @@ public class FrameHandler(INavigationContext navigationContext) :
}
control.DataContext = args.Content;
navigationContext.Set(control);
NavigatedTo(args.Sender, control);
frame.NavigateFromObject(control, new FrameNavigationOptions { TransitionInfoOverride = new SuppressNavigationTransitionInfo() });
}
-8
View File
@@ -1,8 +0,0 @@
using Avalonia.Controls;
namespace Toolkit.Avalonia;
public interface INavigationContext
{
void Set(Control control);
}
@@ -126,7 +126,7 @@ public static class IServiceCollectionExtensions
services.AddTransient<IDispatcher, AvaloniaDispatcher>();
services.AddTransient<IContentTemplate, ContentTemplate>();
services.AddTransient<INavigationContext, NavigationContext>();
services.AddTransient<INavigationRegion, NavigationRegion>();
services.AddNavigateHandler<ClassicDesktopStyleApplicationHandler>();
services.AddNavigateHandler<SingleViewApplicationHandler>();
@@ -134,7 +134,7 @@ public static class IServiceCollectionExtensions
services.AddNavigateHandler<FrameHandler>();
services.AddNavigateHandler<ContentDialogHandler>();
services.AddScoped<INavigationContextCollection, NavigationContextCollection>(provider => new NavigationContextCollection
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>(provider => new NavigationRegionCollection
{
{ typeof(IClassicDesktopStyleApplicationLifetime), typeof(IClassicDesktopStyleApplicationLifetime) },
{ typeof(ISingleViewApplicationLifetime), typeof(ISingleViewApplicationLifetime) }
@@ -148,7 +148,7 @@ public static class IServiceCollectionExtensions
services.AddTransient<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>();
services.AddTransient<IContentTemplate, ContentTemplate>();
services.AddTransient<INavigationContext, NavigationContext>();
services.AddTransient<INavigationRegion, NavigationRegion>();
services.AddNavigateHandler<ContentControlHandler>();
services.AddNavigateHandler<FrameHandler>();
-36
View File
@@ -1,36 +0,0 @@
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using System.Reflection;
using Toolkit.Foundation;
namespace Toolkit.Avalonia;
public class NavigationContext(INavigationContextCollection contexts) :
INavigationContext
{
public void Set(Control control)
{
if (control.GetType().GetCustomAttributes<NavigationTargetAttribute>()
is IEnumerable<NavigationTargetAttribute> attributes)
{
foreach (NavigationTargetAttribute attribute in attributes)
{
if (!contexts.ContainsKey(attribute.Name))
{
if (control.Find<TemplatedControl>(attribute.Name) is TemplatedControl content)
{
contexts.Add(attribute.Name, content);
void HandleUnloaded(object? sender, RoutedEventArgs args)
{
control.Unloaded -= HandleUnloaded;
contexts.Remove(attribute.Name);
}
control.Unloaded += HandleUnloaded;
}
}
}
}
}
}
+28
View File
@@ -0,0 +1,28 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using Toolkit.Foundation;
namespace Toolkit.Avalonia;
public class NavigationRegion(INavigationRegionCollection collection) :
INavigationRegion
{
public void Register(string name,
object target)
{
if (target is Control control)
{
if (!collection.ContainsKey(name))
{
collection.Add(name, control);
void HandleUnloaded(object? sender, RoutedEventArgs args)
{
control.Unloaded -= HandleUnloaded;
collection.Remove(name);
}
control.Unloaded += HandleUnloaded;
}
}
}
}
@@ -5,7 +5,7 @@ using Toolkit.Foundation;
namespace Toolkit.Avalonia;
public class SingleViewApplicationHandler(INavigationContext navigationContext) :
public class SingleViewApplicationHandler :
INavigateHandler<ISingleViewApplicationLifetime>
{
public Task Handle(Navigate<ISingleViewApplicationLifetime> args,
@@ -18,8 +18,6 @@ public class SingleViewApplicationHandler(INavigationContext navigationContext)
{
lifeTime.MainView = control;
control.DataContext = args.Content;
navigationContext.Set(control);
}
}