Improve navigation
This commit is contained in:
@@ -9,7 +9,7 @@ public class ContentControlHandler :
|
|||||||
{
|
{
|
||||||
public async Task Handle(NavigateEventArgs<ContentControl> args)
|
public async Task Handle(NavigateEventArgs<ContentControl> args)
|
||||||
{
|
{
|
||||||
if (args.Context is ContentControl contentControl)
|
if (args.Region is ContentControl contentControl)
|
||||||
{
|
{
|
||||||
if (args.Template is Control control)
|
if (args.Template is Control control)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public class ContentDialogHandler(IDispatcher dispatcher) :
|
|||||||
{
|
{
|
||||||
public async Task Handle(NavigateEventArgs<ContentDialog> args)
|
public async Task Handle(NavigateEventArgs<ContentDialog> args)
|
||||||
{
|
{
|
||||||
if (args.Context is ContentDialog contentDialog)
|
if (args.Region is ContentDialog contentDialog)
|
||||||
{
|
{
|
||||||
contentDialog.DataContext = args.Content;
|
contentDialog.DataContext = args.Content;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public class FrameHandler :
|
|||||||
{
|
{
|
||||||
public Task Handle(NavigateEventArgs<Frame> args)
|
public Task Handle(NavigateEventArgs<Frame> args)
|
||||||
{
|
{
|
||||||
if (args.Context is Frame frame)
|
if (args.Region is Frame frame)
|
||||||
{
|
{
|
||||||
frame.NavigationPageFactory ??= new NavigationPageFactory();
|
frame.NavigationPageFactory ??= new NavigationPageFactory();
|
||||||
if (args.Template is Control control)
|
if (args.Template is Control control)
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
public interface INavigationScope
|
public interface INavigationScope
|
||||||
{
|
{
|
||||||
void Navigate(string route, object? sender = null, object? context = null,
|
void Navigate(string route,
|
||||||
EventHandler? navigated = null, object[]? parameters = null);
|
object? sender = null,
|
||||||
|
object? region = null,
|
||||||
|
EventHandler? navigated = null,
|
||||||
|
object[]? parameters = null);
|
||||||
|
|
||||||
void Back(object? context);
|
void Back(object? region);
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public record NavigateEventArgs(string Route,
|
public record NavigateEventArgs(string Route,
|
||||||
object? Context = null,
|
object? Region = null,
|
||||||
string? Scope = null,
|
string? Scope = null,
|
||||||
object? Sender = null,
|
object? Sender = null,
|
||||||
EventHandler? Navigated = null,
|
EventHandler? Navigated = null,
|
||||||
object[]? Parameters = null);
|
object[]? Parameters = null);
|
||||||
|
|
||||||
public record NavigateEventArgs<TNavigation>(object Context,
|
public record NavigateEventArgs<TNavigation>(object Region,
|
||||||
object Template,
|
object Template,
|
||||||
object Content,
|
object Content,
|
||||||
object? Sender = null,
|
object? Sender = null,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class NavigateHandler(NamedComponent scope,
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigationScope?.Navigate(args.Route, args.Sender,
|
navigationScope?.Navigate(args.Route, args.Sender,
|
||||||
args.Context, args.Navigated, args.Parameters);
|
args.Region, args.Navigated, args.Parameters);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Data.SqlTypes;
|
||||||
|
|
||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
@@ -6,16 +7,21 @@ public class NavigationScope(IPublisher publisher,
|
|||||||
IServiceProvider provider,
|
IServiceProvider provider,
|
||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
INavigationProvider navigationProvider,
|
INavigationProvider navigationProvider,
|
||||||
INavigationRegionProvider navigationContextProvider,
|
INavigationRegionProvider navigationRegionProvider,
|
||||||
IContentTemplateDescriptorProvider contentTemplateDescriptorProvider) :
|
IContentTemplateDescriptorProvider contentTemplateDescriptorProvider) :
|
||||||
INavigationScope
|
INavigationScope
|
||||||
{
|
{
|
||||||
public void Navigate(string route,
|
public void Navigate(string route,
|
||||||
object? sender = null,
|
object? sender = null,
|
||||||
object? context = null,
|
object? region = null,
|
||||||
EventHandler? navigated = null,
|
EventHandler? navigated = null,
|
||||||
object[]? parameters = null)
|
object[]? parameters = null)
|
||||||
{
|
{
|
||||||
|
if (region is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string[] segments = route.Split('/');
|
string[] segments = route.Split('/');
|
||||||
int segmentCount = segments.Length;
|
int segmentCount = segments.Length;
|
||||||
int currentSegmentIndex = 0;
|
int currentSegmentIndex = 0;
|
||||||
@@ -44,28 +50,33 @@ public class NavigationScope(IPublisher publisher,
|
|||||||
|
|
||||||
if (provider.GetRequiredKeyedService(descriptor.TemplateType, segment) is object view)
|
if (provider.GetRequiredKeyedService(descriptor.TemplateType, segment) is object view)
|
||||||
{
|
{
|
||||||
if (context is not null)
|
if (region is not null)
|
||||||
{
|
{
|
||||||
if (navigationContextProvider.TryGet(context, out object? scopedContext))
|
switch (region)
|
||||||
{
|
{
|
||||||
context = scopedContext;
|
case "self":
|
||||||
|
region = view;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (navigationRegionProvider.TryGet(region, out object? value))
|
||||||
|
{
|
||||||
|
region = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
context = view;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context is not null)
|
if (region is not null)
|
||||||
{
|
{
|
||||||
if ((parameters is { Length: > 0 }
|
if ((parameters is { Length: > 0 }
|
||||||
? factory.Create(descriptor.ContentType, parameters)
|
? factory.Create(descriptor.ContentType, parameters)
|
||||||
: provider.GetRequiredKeyedService(descriptor.ContentType, segment)) is object viewModel)
|
: provider.GetRequiredKeyedService(descriptor.ContentType, segment)) is object viewModel)
|
||||||
{
|
{
|
||||||
if (navigationProvider.Get(context is Type type ? type : context.GetType()) is INavigation navigation)
|
if (navigationProvider.Get(region is Type type ? type : region.GetType()) is INavigation navigation)
|
||||||
{
|
{
|
||||||
Type navigateType = typeof(NavigateEventArgs<>).MakeGenericType(navigation.Type);
|
Type navigateType = typeof(NavigateEventArgs<>).MakeGenericType(navigation.Type);
|
||||||
if (Activator.CreateInstance(navigateType, [context, view, viewModel, sender, parameters]) is object navigate)
|
if (Activator.CreateInstance(navigateType, [region, view, viewModel, sender, parameters]) is object navigate)
|
||||||
{
|
{
|
||||||
publisher.Publish(navigate);
|
publisher.Publish(navigate);
|
||||||
if (currentSegmentIndex == segmentCount)
|
if (currentSegmentIndex == segmentCount)
|
||||||
@@ -85,7 +96,7 @@ public class NavigationScope(IPublisher publisher,
|
|||||||
{
|
{
|
||||||
if (context is not null)
|
if (context is not null)
|
||||||
{
|
{
|
||||||
navigationContextProvider.TryGet(context, out context);
|
navigationRegionProvider.TryGet(context, out context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context is not null)
|
if (context is not null)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Metadata;
|
using Avalonia.Metadata;
|
||||||
using Avalonia.Xaml.Interactivity;
|
using Avalonia.Xaml.Interactivity;
|
||||||
@@ -10,9 +11,6 @@ public class NavigateAction :
|
|||||||
AvaloniaObject,
|
AvaloniaObject,
|
||||||
IAction
|
IAction
|
||||||
{
|
{
|
||||||
public static readonly StyledProperty<object> ContextProperty =
|
|
||||||
AvaloniaProperty.Register<NavigateAction, object>(nameof(Context));
|
|
||||||
|
|
||||||
public static readonly DirectProperty<NavigateAction, ParameterBindingCollection> ParameterBindingsProperty =
|
public static readonly DirectProperty<NavigateAction, ParameterBindingCollection> ParameterBindingsProperty =
|
||||||
AvaloniaProperty.RegisterDirect<NavigateAction, ParameterBindingCollection>(nameof(ParameterBindings),
|
AvaloniaProperty.RegisterDirect<NavigateAction, ParameterBindingCollection>(nameof(ParameterBindings),
|
||||||
x => x.ParameterBindings);
|
x => x.ParameterBindings);
|
||||||
@@ -20,6 +18,9 @@ public class NavigateAction :
|
|||||||
public static readonly StyledProperty<object[]?> ParametersProperty =
|
public static readonly StyledProperty<object[]?> ParametersProperty =
|
||||||
AvaloniaProperty.Register<NavigateAction, object[]?>(nameof(Parameters));
|
AvaloniaProperty.Register<NavigateAction, object[]?>(nameof(Parameters));
|
||||||
|
|
||||||
|
public static readonly StyledProperty<object> RegionProperty =
|
||||||
|
AvaloniaProperty.Register<NavigateAction, object>(nameof(Region));
|
||||||
|
|
||||||
public static readonly StyledProperty<string> RouteProperty =
|
public static readonly StyledProperty<string> RouteProperty =
|
||||||
AvaloniaProperty.Register<NavigateAction, string>(nameof(Route));
|
AvaloniaProperty.Register<NavigateAction, string>(nameof(Route));
|
||||||
|
|
||||||
@@ -30,10 +31,10 @@ public class NavigateAction :
|
|||||||
|
|
||||||
public event EventHandler? Navigated;
|
public event EventHandler? Navigated;
|
||||||
|
|
||||||
public object Context
|
public object Region
|
||||||
{
|
{
|
||||||
get => GetValue(ContextProperty);
|
get => GetValue(RegionProperty);
|
||||||
set => SetValue(ContextProperty, value);
|
set => SetValue(RegionProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
@@ -61,12 +62,12 @@ public class NavigateAction :
|
|||||||
public object Execute(object? sender,
|
public object Execute(object? sender,
|
||||||
object? parameter)
|
object? parameter)
|
||||||
{
|
{
|
||||||
if (sender is TemplatedControl control)
|
if (sender is Control content)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> arguments =
|
Dictionary<string, object> arguments =
|
||||||
new(StringComparer.InvariantCultureIgnoreCase);
|
new(StringComparer.InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
if (control.DataContext is IObservableViewModel observableViewModel)
|
if (content.DataContext is IObservableViewModel observableViewModel)
|
||||||
{
|
{
|
||||||
object[] parameters = [.. Parameters ?? Enumerable.Empty<object?>(),
|
object[] parameters = [.. Parameters ?? Enumerable.Empty<object?>(),
|
||||||
..
|
..
|
||||||
@@ -74,8 +75,8 @@ public class NavigateAction :
|
|||||||
ParameterBindings.Select(binding => new KeyValuePair<string, object>(binding.Key, binding.Value)).ToArray() :
|
ParameterBindings.Select(binding => new KeyValuePair<string, object>(binding.Key, binding.Value)).ToArray() :
|
||||||
Enumerable.Empty<KeyValuePair<string, object>>()];
|
Enumerable.Empty<KeyValuePair<string, object>>()];
|
||||||
|
|
||||||
observableViewModel.Publisher.Publish(new NavigateEventArgs(Route, Context == this ? control : Context, Scope ?? null,
|
observableViewModel.Publisher.Publish(new NavigateEventArgs(Route, Region == this ? content : Region, Scope ?? null,
|
||||||
control.DataContext, Navigated, parameters));
|
content.DataContext, Navigated, parameters));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,16 +9,16 @@ public class NavigateBackAction :
|
|||||||
AvaloniaObject,
|
AvaloniaObject,
|
||||||
IAction
|
IAction
|
||||||
{
|
{
|
||||||
public static readonly StyledProperty<string> ContextProperty =
|
public static readonly StyledProperty<string> RegionProperty =
|
||||||
AvaloniaProperty.Register<NavigateBackAction, string>(nameof(Context));
|
AvaloniaProperty.Register<NavigateBackAction, string>(nameof(Region));
|
||||||
|
|
||||||
public static readonly StyledProperty<string> ScopeProperty =
|
public static readonly StyledProperty<string> ScopeProperty =
|
||||||
AvaloniaProperty.Register<NavigateBackAction, string>(nameof(Scope));
|
AvaloniaProperty.Register<NavigateBackAction, string>(nameof(Scope));
|
||||||
|
|
||||||
public string Context
|
public string Region
|
||||||
{
|
{
|
||||||
get => GetValue(ContextProperty);
|
get => GetValue(RegionProperty);
|
||||||
set => SetValue(ContextProperty, value);
|
set => SetValue(RegionProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Scope
|
public string Scope
|
||||||
@@ -34,7 +34,7 @@ public class NavigateBackAction :
|
|||||||
{
|
{
|
||||||
if (control.DataContext is IObservableViewModel observableViewModel)
|
if (control.DataContext is IObservableViewModel observableViewModel)
|
||||||
{
|
{
|
||||||
observableViewModel.Publisher.Publish(new NavigateBackEventArgs(Context
|
observableViewModel.Publisher.Publish(new NavigateBackEventArgs(Region
|
||||||
?? null, Scope ?? null));
|
?? null, Scope ?? null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user