Improvement to navigation regions
This commit is contained in:
@@ -5,7 +5,7 @@ using Toolkit.Foundation;
|
|||||||
|
|
||||||
namespace Toolkit.Avalonia;
|
namespace Toolkit.Avalonia;
|
||||||
|
|
||||||
public class ClassicDesktopStyleApplicationHandler(INavigationContext navigationContext) :
|
public class ClassicDesktopStyleApplicationHandler :
|
||||||
INavigateHandler<IClassicDesktopStyleApplicationLifetime>
|
INavigateHandler<IClassicDesktopStyleApplicationLifetime>
|
||||||
{
|
{
|
||||||
public Task Handle(Navigate<IClassicDesktopStyleApplicationLifetime> args,
|
public Task Handle(Navigate<IClassicDesktopStyleApplicationLifetime> args,
|
||||||
@@ -18,8 +18,6 @@ public class ClassicDesktopStyleApplicationHandler(INavigationContext navigation
|
|||||||
{
|
{
|
||||||
lifeTime.MainWindow = window;
|
lifeTime.MainWindow = window;
|
||||||
window.DataContext = args.Content;
|
window.DataContext = args.Content;
|
||||||
|
|
||||||
navigationContext.Set(window);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using Toolkit.Foundation;
|
|||||||
|
|
||||||
namespace Toolkit.Avalonia;
|
namespace Toolkit.Avalonia;
|
||||||
|
|
||||||
public class ContentControlHandler(INavigationContext navigationContext) :
|
public class ContentControlHandler :
|
||||||
INavigateHandler<ContentControl>
|
INavigateHandler<ContentControl>
|
||||||
{
|
{
|
||||||
public async Task Handle(Navigate<ContentControl> args,
|
public async Task Handle(Navigate<ContentControl> args,
|
||||||
@@ -51,8 +51,6 @@ public class ContentControlHandler(INavigationContext navigationContext) :
|
|||||||
|
|
||||||
control.DataContext = args.Content;
|
control.DataContext = args.Content;
|
||||||
contentControl.Content = control;
|
contentControl.Content = control;
|
||||||
|
|
||||||
navigationContext.Set(control);
|
|
||||||
await taskCompletionSource.Task;
|
await taskCompletionSource.Task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class ContentTemplate :
|
|||||||
if (observableViewModel.Provider is IServiceProvider provider)
|
if (observableViewModel.Provider is IServiceProvider provider)
|
||||||
{
|
{
|
||||||
IContentTemplateDescriptorProvider? contentTemplateProvider = provider.GetService<IContentTemplateDescriptorProvider>();
|
IContentTemplateDescriptorProvider? contentTemplateProvider = provider.GetService<IContentTemplateDescriptorProvider>();
|
||||||
INavigationContext? viewModelContentBinder = provider.GetService<INavigationContext>();
|
INavigationRegion? viewModelContentBinder = provider.GetService<INavigationRegion>();
|
||||||
|
|
||||||
if (contentTemplateProvider?.Get(item.GetType().Name) is IContentTemplateDescriptor descriptor)
|
if (contentTemplateProvider?.Get(item.GetType().Name) is IContentTemplateDescriptor descriptor)
|
||||||
{
|
{
|
||||||
@@ -55,7 +55,7 @@ public class ContentTemplate :
|
|||||||
control.Loaded += HandleLoaded;
|
control.Loaded += HandleLoaded;
|
||||||
control.Unloaded += HandleUnloaded;
|
control.Unloaded += HandleUnloaded;
|
||||||
|
|
||||||
viewModelContentBinder?.Set(control);
|
//viewModelContentBinder?.Register(control);
|
||||||
|
|
||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Toolkit.UI.Controls.Avalonia;
|
|||||||
|
|
||||||
namespace Toolkit.Avalonia;
|
namespace Toolkit.Avalonia;
|
||||||
|
|
||||||
public class FrameHandler(INavigationContext navigationContext) :
|
public class FrameHandler :
|
||||||
INavigateHandler<Frame>,
|
INavigateHandler<Frame>,
|
||||||
INavigateBackHandler<Frame>
|
INavigateBackHandler<Frame>
|
||||||
{
|
{
|
||||||
@@ -45,32 +45,6 @@ public class FrameHandler(INavigationContext navigationContext) :
|
|||||||
{
|
{
|
||||||
await deactivating.Deactivating();
|
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();
|
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;
|
control.DataContext = args.Content;
|
||||||
navigationContext.Set(control);
|
|
||||||
|
|
||||||
NavigatedTo(args.Sender, control);
|
NavigatedTo(args.Sender, control);
|
||||||
frame.NavigateFromObject(control, new FrameNavigationOptions { TransitionInfoOverride = new SuppressNavigationTransitionInfo() });
|
frame.NavigateFromObject(control, new FrameNavigationOptions { TransitionInfoOverride = new SuppressNavigationTransitionInfo() });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<IDispatcher, AvaloniaDispatcher>();
|
||||||
|
|
||||||
services.AddTransient<IContentTemplate, ContentTemplate>();
|
services.AddTransient<IContentTemplate, ContentTemplate>();
|
||||||
services.AddTransient<INavigationContext, NavigationContext>();
|
services.AddTransient<INavigationRegion, NavigationRegion>();
|
||||||
|
|
||||||
services.AddNavigateHandler<ClassicDesktopStyleApplicationHandler>();
|
services.AddNavigateHandler<ClassicDesktopStyleApplicationHandler>();
|
||||||
services.AddNavigateHandler<SingleViewApplicationHandler>();
|
services.AddNavigateHandler<SingleViewApplicationHandler>();
|
||||||
@@ -134,7 +134,7 @@ public static class IServiceCollectionExtensions
|
|||||||
services.AddNavigateHandler<FrameHandler>();
|
services.AddNavigateHandler<FrameHandler>();
|
||||||
services.AddNavigateHandler<ContentDialogHandler>();
|
services.AddNavigateHandler<ContentDialogHandler>();
|
||||||
|
|
||||||
services.AddScoped<INavigationContextCollection, NavigationContextCollection>(provider => new NavigationContextCollection
|
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>(provider => new NavigationRegionCollection
|
||||||
{
|
{
|
||||||
{ typeof(IClassicDesktopStyleApplicationLifetime), typeof(IClassicDesktopStyleApplicationLifetime) },
|
{ typeof(IClassicDesktopStyleApplicationLifetime), typeof(IClassicDesktopStyleApplicationLifetime) },
|
||||||
{ typeof(ISingleViewApplicationLifetime), typeof(ISingleViewApplicationLifetime) }
|
{ typeof(ISingleViewApplicationLifetime), typeof(ISingleViewApplicationLifetime) }
|
||||||
@@ -148,7 +148,7 @@ public static class IServiceCollectionExtensions
|
|||||||
services.AddTransient<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>();
|
services.AddTransient<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>();
|
||||||
services.AddTransient<IContentTemplate, ContentTemplate>();
|
services.AddTransient<IContentTemplate, ContentTemplate>();
|
||||||
|
|
||||||
services.AddTransient<INavigationContext, NavigationContext>();
|
services.AddTransient<INavigationRegion, NavigationRegion>();
|
||||||
|
|
||||||
services.AddNavigateHandler<ContentControlHandler>();
|
services.AddNavigateHandler<ContentControlHandler>();
|
||||||
services.AddNavigateHandler<FrameHandler>();
|
services.AddNavigateHandler<FrameHandler>();
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
namespace Toolkit.Avalonia;
|
||||||
|
|
||||||
public class SingleViewApplicationHandler(INavigationContext navigationContext) :
|
public class SingleViewApplicationHandler :
|
||||||
INavigateHandler<ISingleViewApplicationLifetime>
|
INavigateHandler<ISingleViewApplicationLifetime>
|
||||||
{
|
{
|
||||||
public Task Handle(Navigate<ISingleViewApplicationLifetime> args,
|
public Task Handle(Navigate<ISingleViewApplicationLifetime> args,
|
||||||
@@ -18,8 +18,6 @@ public class SingleViewApplicationHandler(INavigationContext navigationContext)
|
|||||||
{
|
{
|
||||||
lifeTime.MainView = control;
|
lifeTime.MainView = control;
|
||||||
control.DataContext = args.Content;
|
control.DataContext = args.Content;
|
||||||
|
|
||||||
navigationContext.Set(control);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ public class ComponentBuilder :
|
|||||||
services.AddTransient<INavigationScope, NavigationScope>();
|
services.AddTransient<INavigationScope, NavigationScope>();
|
||||||
|
|
||||||
services.AddTransient<INavigationProvider, NavigationProvider>();
|
services.AddTransient<INavigationProvider, NavigationProvider>();
|
||||||
services.AddScoped<INavigationContextCollection, NavigationContextCollection>();
|
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>();
|
||||||
services.AddTransient<INavigationContextProvider, NavigationContextProvider>();
|
services.AddTransient<INavigationRegionProvider, NavigationRegionProvider>();
|
||||||
|
|
||||||
services.AddHandler<NavigateHandler>();
|
services.AddHandler<NavigateHandler>();
|
||||||
services.AddHandler<NavigateBackHandler>();
|
services.AddHandler<NavigateBackHandler>();
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ public class ComponentFactory(IServiceProvider provider,
|
|||||||
provider.GetRequiredService<IProxyService<IComponentHostCollection>>());
|
provider.GetRequiredService<IProxyService<IComponentHostCollection>>());
|
||||||
|
|
||||||
services.AddScoped(_ =>
|
services.AddScoped(_ =>
|
||||||
provider.GetRequiredService<INavigationContextCollection>());
|
provider.GetRequiredService<INavigationRegionCollection>());
|
||||||
|
|
||||||
services.AddScoped(_ =>
|
services.AddScoped(_ =>
|
||||||
provider.GetRequiredService<INavigationContextProvider>());
|
provider.GetRequiredService<INavigationRegionProvider>());
|
||||||
|
|
||||||
services.AddScoped(_ =>
|
services.AddScoped(_ =>
|
||||||
provider.GetRequiredService<IComponentScopeCollection>());
|
provider.GetRequiredService<IComponentScopeCollection>());
|
||||||
@@ -37,7 +37,7 @@ public class ComponentFactory(IServiceProvider provider,
|
|||||||
provider.GetRequiredService<IComponentScopeProvider>());
|
provider.GetRequiredService<IComponentScopeProvider>());
|
||||||
|
|
||||||
services.AddRange(proxy.Services);
|
services.AddRange(proxy.Services);
|
||||||
services.AddSingleton(new ComponentScope(name));
|
services.AddSingleton(new NamedComponent(name));
|
||||||
|
|
||||||
if (servicesDelegate is not null)
|
if (servicesDelegate is not null)
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ public class ComponentFactory(IServiceProvider provider,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.AddConfiguration<TConfiguration>(name, configuration);
|
builder.AddConfiguration(name, configuration);
|
||||||
IComponentHost host = builder.Build();
|
IComponentHost host = builder.Build();
|
||||||
|
|
||||||
scopes.Add(new ComponentScopeDescriptor(name,
|
scopes.Add(new ComponentScopeDescriptor(name,
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ public class ComponentInitializer(IEnumerable<IComponent> components,
|
|||||||
provider.GetRequiredService<IProxyService<IComponentHostCollection>>());
|
provider.GetRequiredService<IProxyService<IComponentHostCollection>>());
|
||||||
|
|
||||||
services.AddScoped(_ =>
|
services.AddScoped(_ =>
|
||||||
provider.GetRequiredService<INavigationContextCollection>());
|
provider.GetRequiredService<INavigationRegionCollection>());
|
||||||
|
|
||||||
services.AddScoped(_ =>
|
services.AddScoped(_ =>
|
||||||
provider.GetRequiredService<INavigationContextProvider>());
|
provider.GetRequiredService<INavigationRegionProvider>());
|
||||||
|
|
||||||
services.AddScoped(_ =>
|
services.AddScoped(_ =>
|
||||||
provider.GetRequiredService<IComponentScopeCollection>());
|
provider.GetRequiredService<IComponentScopeCollection>());
|
||||||
@@ -36,7 +36,7 @@ public class ComponentInitializer(IEnumerable<IComponent> components,
|
|||||||
|
|
||||||
services.AddRange(typedServices.Services);
|
services.AddRange(typedServices.Services);
|
||||||
|
|
||||||
services.AddSingleton(new ComponentScope(component.GetType().Name));
|
services.AddSingleton(new NamedComponent(component.GetType().Name));
|
||||||
});
|
});
|
||||||
|
|
||||||
IComponentHost host = builder.Build();
|
IComponentHost host = builder.Build();
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public record ComponentScope(string Name);
|
|
||||||
@@ -33,8 +33,8 @@ public class DefaultHostBuilder :
|
|||||||
services.AddScoped<IProxyService<IPublisher>>(provider =>
|
services.AddScoped<IProxyService<IPublisher>>(provider =>
|
||||||
new ProxyService<IPublisher>(provider.GetRequiredService<IPublisher>()));
|
new ProxyService<IPublisher>(provider.GetRequiredService<IPublisher>()));
|
||||||
|
|
||||||
services.AddScoped<IProxyService<INavigationContextProvider>>(provider =>
|
services.AddScoped<IProxyService<INavigationRegionProvider>>(provider =>
|
||||||
new ProxyService<INavigationContextProvider>(provider.GetRequiredService<INavigationContextProvider>()));
|
new ProxyService<INavigationRegionProvider>(provider.GetRequiredService<INavigationRegionProvider>()));
|
||||||
|
|
||||||
services.AddScoped<IProxyService<IComponentHostCollection>>(provider =>
|
services.AddScoped<IProxyService<IComponentHostCollection>>(provider =>
|
||||||
new ProxyService<IComponentHostCollection>(provider.GetRequiredService<IComponentHostCollection>()));
|
new ProxyService<IComponentHostCollection>(provider.GetRequiredService<IComponentHostCollection>()));
|
||||||
@@ -45,12 +45,12 @@ public class DefaultHostBuilder :
|
|||||||
|
|
||||||
services.AddTransient<INavigationProvider, NavigationProvider>();
|
services.AddTransient<INavigationProvider, NavigationProvider>();
|
||||||
|
|
||||||
services.AddScoped<INavigationContextCollection, NavigationContextCollection>();
|
services.AddScoped<INavigationRegionCollection, NavigationRegionCollection>();
|
||||||
services.AddTransient<INavigationContextProvider, NavigationContextProvider>();
|
services.AddTransient<INavigationRegionProvider, NavigationRegionProvider>();
|
||||||
|
|
||||||
services.AddTransient<INavigationScope, NavigationScope>();
|
services.AddTransient<INavigationScope, NavigationScope>();
|
||||||
|
|
||||||
services.AddSingleton(new ComponentScope("Root"));
|
services.AddSingleton(new NamedComponent("Root"));
|
||||||
services.AddScoped<IComponentScopeCollection, ComponentScopeCollection>(provider => new ComponentScopeCollection
|
services.AddScoped<IComponentScopeCollection, ComponentScopeCollection>(provider => new ComponentScopeCollection
|
||||||
{
|
{
|
||||||
new ComponentScopeDescriptor("Root", provider.GetRequiredService<IServiceProvider>())
|
new ComponentScopeDescriptor("Root", provider.GetRequiredService<IServiceProvider>())
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public interface INavigationRegion
|
||||||
|
{
|
||||||
|
void Register(string name,
|
||||||
|
object target);
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public interface INavigationContextCollection :
|
public interface INavigationRegionCollection :
|
||||||
IDictionary<object, object?>;
|
IDictionary<object, object?>;
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public interface INavigationContextProvider
|
public interface INavigationRegionProvider
|
||||||
{
|
{
|
||||||
object? Get(object key);
|
object? Get(object key);
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public record NamedComponent(string Name)
|
||||||
|
{
|
||||||
|
public override string ToString() => Name;
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public class NavigateHandler(ComponentScope scope,
|
public class NavigateHandler(NamedComponent scope,
|
||||||
IComponentScopeProvider provider) :
|
IComponentScopeProvider provider) :
|
||||||
INotificationHandler<Navigate>
|
INotificationHandler<Navigate>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
|
||||||
public class NavigationContextAttribute : Attribute
|
|
||||||
{
|
|
||||||
public NavigationContextAttribute(string name)
|
|
||||||
{
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name { get; }
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
namespace Toolkit.Foundation;
|
|
||||||
|
|
||||||
public class NavigationContextCollection : Dictionary<object, object?>,
|
|
||||||
INavigationContextCollection;
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
|
public class NavigationRegionCollection : Dictionary<object, object?>,
|
||||||
|
INavigationRegionCollection;
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
namespace Toolkit.Foundation;
|
namespace Toolkit.Foundation;
|
||||||
|
|
||||||
public class NavigationContextProvider(INavigationContextCollection contexts) :
|
public class NavigationRegionProvider(INavigationRegionCollection contexts) :
|
||||||
INavigationContextProvider
|
INavigationRegionProvider
|
||||||
{
|
{
|
||||||
public object? Get(object key) =>
|
public object? Get(object key) =>
|
||||||
contexts.TryGetValue(key, out object? target) ? target : default;
|
contexts.TryGetValue(key, out object? target) ? target : default;
|
||||||
@@ -6,7 +6,7 @@ public class NavigationScope(IPublisher publisher,
|
|||||||
IServiceProvider provider,
|
IServiceProvider provider,
|
||||||
IServiceFactory factory,
|
IServiceFactory factory,
|
||||||
INavigationProvider navigationProvider,
|
INavigationProvider navigationProvider,
|
||||||
INavigationContextProvider navigationContextProvider,
|
INavigationRegionProvider navigationContextProvider,
|
||||||
IContentTemplateDescriptorProvider contentTemplateDescriptorProvider) :
|
IContentTemplateDescriptorProvider contentTemplateDescriptorProvider) :
|
||||||
INavigationScope
|
INavigationScope
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ public class ConditionAction :
|
|||||||
IAction
|
IAction
|
||||||
{
|
{
|
||||||
public static readonly DirectProperty<ConditionAction, ActionCollection> ActionsProperty =
|
public static readonly DirectProperty<ConditionAction, ActionCollection> ActionsProperty =
|
||||||
AvaloniaProperty.RegisterDirect<ConditionAction, ActionCollection>(nameof(Actions),
|
AvaloniaProperty.RegisterDirect<ConditionAction, ActionCollection>(nameof(Actions), x => x.Actions);
|
||||||
x => x.Actions);
|
|
||||||
|
|
||||||
public static readonly StyledProperty<ICondition> ConditionProperty =
|
public static readonly StyledProperty<ICondition> ConditionProperty =
|
||||||
AvaloniaProperty.Register<ConditionAction, ICondition>(nameof(Condition));
|
AvaloniaProperty.Register<ConditionAction, ICondition>(nameof(Condition));
|
||||||
|
|||||||
@@ -74,7 +74,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 Navigate(Route, Context == this ? control : Context, Scope ?? null, control.DataContext, Navigated, parameters));
|
observableViewModel.Publisher.Publish(new Navigate(Route, Context == this ? control : Context, Scope ?? null,
|
||||||
|
control.DataContext, Navigated, parameters)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class NavigateBackAction :
|
|||||||
if (control.DataContext is IObservableViewModel observableViewModel)
|
if (control.DataContext is IObservableViewModel observableViewModel)
|
||||||
{
|
{
|
||||||
observableViewModel.Publisher.Publish(new NavigateBack(Context
|
observableViewModel.Publisher.Publish(new NavigateBack(Context
|
||||||
?? null, Scope ?? null)).GetAwaiter().GetResult();
|
?? null, Scope ?? null)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Metadata;
|
||||||
|
using Avalonia.Xaml.Interactivity;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Toolkit.Foundation;
|
||||||
|
|
||||||
|
namespace Toolkit.UI.Avalonia;
|
||||||
|
|
||||||
|
public class NavigateRegionAction :
|
||||||
|
AvaloniaObject,
|
||||||
|
IAction
|
||||||
|
{
|
||||||
|
public static readonly DirectProperty<NavigateRegionAction, ActionCollection> ActionsProperty =
|
||||||
|
AvaloniaProperty.RegisterDirect<NavigateRegionAction, ActionCollection>(nameof(Actions), x => x.Actions);
|
||||||
|
|
||||||
|
public static readonly StyledProperty<string> NameProperty =
|
||||||
|
AvaloniaProperty.Register<NavigateRegionAction, string>(nameof(Name));
|
||||||
|
|
||||||
|
private ActionCollection? actions;
|
||||||
|
|
||||||
|
[Content]
|
||||||
|
public ActionCollection Actions => actions ??= [];
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => GetValue(NameProperty);
|
||||||
|
set => SetValue(NameProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object? Execute(object? sender,
|
||||||
|
object? parameter)
|
||||||
|
{
|
||||||
|
if (sender is Control control)
|
||||||
|
{
|
||||||
|
if (control.DataContext is IObservableViewModel observableViewModel)
|
||||||
|
{
|
||||||
|
if (observableViewModel.Provider.GetRequiredService<INavigationRegion>() is INavigationRegion navigationRegion)
|
||||||
|
{
|
||||||
|
navigationRegion.Register(Name, sender);
|
||||||
|
Interaction.ExecuteActions(sender, Actions, parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,24 @@
|
|||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:controls="using:Toolkit.UI.Controls.Avalonia">
|
xmlns:controls="using:Toolkit.UI.Controls.Avalonia">
|
||||||
|
<ResourceDictionary.ThemeDictionaries>
|
||||||
|
<ResourceDictionary x:Key="Light">
|
||||||
|
<StaticResource x:Key="PersonPictureForegroundThemeBrush" ResourceKey="TextFillColorPrimaryBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseBadgeForegroundThemeBrush" ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseBadgeFillThemeBrush" ResourceKey="AccentFillColorDefaultBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseBadgeStrokeThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseFillThemeBrush" ResourceKey="ControlAltFillColorQuarternaryBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseFillStrokeBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
||||||
|
</ResourceDictionary>
|
||||||
|
<ResourceDictionary x:Key="Dark">
|
||||||
|
<StaticResource x:Key="PersonPictureForegroundThemeBrush" ResourceKey="TextFillColorPrimaryBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseBadgeForegroundThemeBrush" ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseBadgeFillThemeBrush" ResourceKey="AccentFillColorDefaultBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseBadgeStrokeThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseFillThemeBrush" ResourceKey="ControlAltFillColorQuarternaryBrush" />
|
||||||
|
<StaticResource x:Key="PersonPictureEllipseFillStrokeBrush" ResourceKey="CardStrokeColorDefaultBrush" />
|
||||||
|
</ResourceDictionary>
|
||||||
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
<x:Double x:Key="PersonPictureEllipseBadgeStrokeOpacity">1</x:Double>
|
<x:Double x:Key="PersonPictureEllipseBadgeStrokeOpacity">1</x:Double>
|
||||||
<x:Double x:Key="PersonPictureEllipseBadgeImageSourceStrokeOpacity">1</x:Double>
|
<x:Double x:Key="PersonPictureEllipseBadgeImageSourceStrokeOpacity">1</x:Double>
|
||||||
<x:Double x:Key="PersonPictureEllipseStrokeThickness">1</x:Double>
|
<x:Double x:Key="PersonPictureEllipseStrokeThickness">1</x:Double>
|
||||||
|
|||||||
@@ -2,39 +2,41 @@
|
|||||||
|
|
||||||
internal class PersonPictureInitialsGenerator
|
internal class PersonPictureInitialsGenerator
|
||||||
{
|
{
|
||||||
public static PersonPictureCharacterType GetCharacterType(string str)
|
public static PersonPictureCharacterType GetCharacterType(string content)
|
||||||
{
|
{
|
||||||
|
|
||||||
PersonPictureCharacterType result = PersonPictureCharacterType.Other;
|
PersonPictureCharacterType result = PersonPictureCharacterType.Other;
|
||||||
for (int i = 0; i < 3; i++)
|
if (content is { Length: > 0 })
|
||||||
{
|
{
|
||||||
if ((i >= str.Length) || (str[i] == '\0') || (str[i] == 0xFEFF))
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
break;
|
if ((i >= content.Length) || (content[i] == '\0') || (content[i] == 0xFEFF))
|
||||||
}
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
char character = str[i];
|
char character = content[i];
|
||||||
PersonPictureCharacterType evaluationResult = GetCharacterType(character);
|
PersonPictureCharacterType evaluationResult = GetCharacterType(character);
|
||||||
|
|
||||||
switch (evaluationResult)
|
switch (evaluationResult)
|
||||||
{
|
{
|
||||||
case PersonPictureCharacterType.Glyph:
|
case PersonPictureCharacterType.Glyph:
|
||||||
result = PersonPictureCharacterType.Glyph;
|
result = PersonPictureCharacterType.Glyph;
|
||||||
break;
|
break;
|
||||||
case PersonPictureCharacterType.Symbolic:
|
case PersonPictureCharacterType.Symbolic:
|
||||||
if (result != PersonPictureCharacterType.Glyph)
|
if (result != PersonPictureCharacterType.Glyph)
|
||||||
{
|
{
|
||||||
result = PersonPictureCharacterType.Symbolic;
|
result = PersonPictureCharacterType.Symbolic;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PersonPictureCharacterType.Standard:
|
case PersonPictureCharacterType.Standard:
|
||||||
if ((result != PersonPictureCharacterType.Glyph) && (result != PersonPictureCharacterType.Symbolic))
|
if ((result != PersonPictureCharacterType.Glyph) && (result != PersonPictureCharacterType.Symbolic))
|
||||||
{
|
{
|
||||||
result = PersonPictureCharacterType.Standard;
|
result = PersonPictureCharacterType.Standard;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<MergeResourceInclude Source="../ContentDialog/ContentDialog.axaml" />
|
<MergeResourceInclude Source="../ContentDialog/ContentDialog.axaml" />
|
||||||
<MergeResourceInclude Source="../SettingsExpander/SettingsExpander.axaml" />
|
<MergeResourceInclude Source="../SettingsExpander/SettingsExpander.axaml" />
|
||||||
<MergeResourceInclude Source="../SettingsExpander/SettingsExpanderItem.axaml" />
|
<MergeResourceInclude Source="../SettingsExpander/SettingsExpanderItem.axaml" />
|
||||||
|
<MergeResourceInclude Source="../PersonPicture/PersonPicture.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user