Add Content lookup markupextension

This commit is contained in:
Daniel Clark
2022-12-14 20:07:45 +00:00
parent b77ee21d56
commit f7e682e0db
32 changed files with 783 additions and 229 deletions
@@ -0,0 +1,51 @@
using Avalonia;
using Mediator;
using System.Diagnostics;
using Toolkit.Framework.Foundation;
namespace Toolkit.Framework.Avalonia;
public class ContentHandler : IRequestHandler<Content, object?>
{
private readonly INamedContentTemplateFactory namedContentTemplateFactory;
private readonly INamedContentFactory namedContentFactory;
private readonly IContentTemplateFactory contentTemplateFactory;
private readonly ITypedContentFactory typedContentFactory;
public ContentHandler(IContentTemplateFactory contentTemplateFactory,
INamedContentFactory namedContentFactory,
INamedContentTemplateFactory namedContentTemplateFactory,
ITypedContentFactory typedContentFactory)
{
this.contentTemplateFactory = contentTemplateFactory;
this.namedContentFactory = namedContentFactory;
this.namedContentTemplateFactory = namedContentTemplateFactory;
this.typedContentFactory = typedContentFactory;
}
public ValueTask<object?> Handle(Content request, CancellationToken cancellationToken)
{
object? content = null;
object? template = null;
if (request.Name is { Length: > 0 } name)
{
content = namedContentFactory.Create(name, request.Parameters);
template = namedContentTemplateFactory.Create(name);
}
if (request.Type is Type type)
{
content = typedContentFactory.Create(type, request.Parameters);
template = contentTemplateFactory.Create(content);
}
if (template is Visual visual)
{
visual.DataContext = content;
return new ValueTask<object?>(visual);
}
return default;
}
}
@@ -1,17 +1,16 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using System.Diagnostics;
using Toolkit.Framework.Foundation; using Toolkit.Framework.Foundation;
namespace Toolkit.Framework.Avalonia; namespace Toolkit.Framework.Avalonia;
public class TemplateSelector : IDataTemplate, ITemplateSelector public class ContentTemplateSelector : IDataTemplate, IContentTemplateSelector
{ {
private readonly Dictionary<object, IControl> dataTracking = new(); private readonly Dictionary<object, IControl> dataTracking = new();
private readonly ITemplateFactory templateFactory; private readonly IContentTemplateFactory templateFactory;
public TemplateSelector(ITemplateFactory templateFactory) public ContentTemplateSelector(IContentTemplateFactory templateFactory)
{ {
this.templateFactory = templateFactory; this.templateFactory = templateFactory;
} }
@@ -7,22 +7,22 @@ namespace Toolkit.Framework.Avalonia;
public static class IHostBuilderExtensions public static class IHostBuilderExtensions
{ {
public static IHostBuilder ConfigureTemplates(this IHostBuilder hostBuilder, Action<ITemplateBuilder> builderDelegate) public static IHostBuilder ConfigureTemplates(this IHostBuilder hostBuilder, Action<IContentTemplateBuilder> builderDelegate)
{ {
hostBuilder.ConfigureServices((hostBuilderContext, serviceCollection) => hostBuilder.ConfigureServices((hostBuilderContext, serviceCollection) =>
{ {
TemplateBuilder? builder = new(); ContentTemplateBuilder? builder = new();
builderDelegate?.Invoke(builder); builderDelegate?.Invoke(builder);
serviceCollection.TryAddSingleton(builder.Descriptors); serviceCollection.TryAddSingleton(builder.Descriptors);
serviceCollection.TryAddSingleton<ITemplateDescriptorProvider, TemplateDescriptorProvider>(); serviceCollection.TryAddSingleton<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>();
serviceCollection.TryAddSingleton<ITemplateFactory, TemplateFactory>(); serviceCollection.TryAddSingleton<IContentTemplateFactory, ContentTemplateFactory>();
serviceCollection.TryAddSingleton<INamedTemplateFactory, NamedTemplateFactory>(); serviceCollection.TryAddSingleton<INamedContentFactory, NamedContentFactory>();
serviceCollection.TryAddSingleton<ITypedDataTemplateFactory, TypedDataTemplateFactory>(); serviceCollection.TryAddSingleton<ITypedContentFactory, TypedContentFactory>();
serviceCollection.TryAddSingleton<INamedDataTemplateFactory, NamedDataTemplateFactory>(); serviceCollection.TryAddSingleton<INamedContentTemplateFactory, NamedContentTemplateFactory>();
serviceCollection.TryAddSingleton<ITemplateSelector, TemplateSelector>(); serviceCollection.TryAddSingleton<IContentTemplateSelector, ContentTemplateSelector>();
foreach (ITemplateDescriptor? descriptor in builder.Descriptors) foreach (IContentTemplateDescriptor? descriptor in builder.Descriptors)
{ {
serviceCollection.Add(new ServiceDescriptor(descriptor.TemplateType, descriptor.TemplateType, descriptor.Lifetime)); serviceCollection.Add(new ServiceDescriptor(descriptor.TemplateType, descriptor.TemplateType, descriptor.Lifetime));
serviceCollection.Add(new ServiceDescriptor(descriptor.ContentType, descriptor.ContentType, descriptor.Lifetime)); serviceCollection.Add(new ServiceDescriptor(descriptor.ContentType, descriptor.ContentType, descriptor.Lifetime));
@@ -0,0 +1,491 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Mediator;
using System.Diagnostics;
using Toolkit.Framework.Foundation;
namespace Toolkit.Framework.Avalonia;
public class ContentExtension : MarkupExtension
{
private static readonly AttachedProperty<IMediator> MediatorProperty =
AvaloniaProperty.RegisterAttached<ContentExtension, AvaloniaObject, IMediator>("Mediator");
private static readonly AttachedProperty<object> ParameterProperty =
AvaloniaProperty.RegisterAttached<ContentExtension, AvaloniaObject, object>("Parameter");
private static readonly AvaloniaProperty ToProperty =
AvaloniaProperty.RegisterAttached<ContentExtension, AvaloniaObject, object>("To");
private readonly Binding? mediatorBinding;
private readonly List<object?> parameters = new();
private readonly Binding? toBinding;
public ContentExtension(object mediator,
object to)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
}
public ContentExtension(object mediator,
object to,
object args1)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7,
object args8)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7,
object args8,
object args9)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7,
object args8,
object args9,
object args10)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7,
object args8,
object args9,
object args10,
object args11)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7,
object args8,
object args9,
object args10,
object args11,
object args12)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
parameters.Add(args12 is MarkupExtension ? args12 : args12.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7,
object args8,
object args9,
object args10,
object args11,
object args12,
object args13)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
parameters.Add(args12 is MarkupExtension ? args12 : args12.ToBinding());
parameters.Add(args13 is MarkupExtension ? args13 : args13.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7,
object args8,
object args9,
object args10,
object args11,
object args12,
object args13,
object args14)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
parameters.Add(args12 is MarkupExtension ? args12 : args12.ToBinding());
parameters.Add(args13 is MarkupExtension ? args13 : args13.ToBinding());
parameters.Add(args14 is MarkupExtension ? args14 : args14.ToBinding());
}
public ContentExtension(object mediator,
object to,
object args1,
object args2,
object args3,
object args4,
object args5,
object args6,
object args7,
object args8,
object args9,
object args10,
object args11,
object args12,
object args13,
object args14,
object args15)
{
mediatorBinding = mediator.ToBinding();
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
parameters.Add(args12 is MarkupExtension ? args12 : args12.ToBinding());
parameters.Add(args13 is MarkupExtension ? args13 : args13.ToBinding());
parameters.Add(args14 is MarkupExtension ? args14 : args14.ToBinding());
parameters.Add(args15 is MarkupExtension ? args15 : args15.ToBinding());
}
public override object? ProvideValue(IServiceProvider serviceProvider)
{
if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target)
{
AvaloniaObject? targetObject = null;
if (target.TargetObject is AvaloniaObject avaloniaObject)
{
targetObject = avaloniaObject;
}
else if (serviceProvider.GetService(typeof(IRootObjectProvider)) is IRootObjectProvider root)
{
targetObject = (AvaloniaObject)root.RootObject;
}
if (targetObject is not null && toBinding is not null && mediatorBinding is not null)
{
if (target.TargetProperty is StyledProperty<object> targetProperty)
{
if (targetObject is Control control)
{
void SetContent()
{
targetObject.Bind(MediatorProperty, mediatorBinding);
if (targetObject.GetValue(MediatorProperty) is IMediator mediator)
{
targetObject.Bind(ToProperty, toBinding);
if (targetObject.GetValue(ToProperty) is { } to)
{
List<object>? parameters = new();
foreach (object? parameter in this.parameters)
{
if (parameter is not null)
{
switch (parameter)
{
case IParameter keyedParameter:
if (keyedParameter.GetValue(targetObject) is KeyValuePair<string, object> keyValuePair)
{
parameters.Add(keyValuePair);
}
break;
default:
if (parameter.ToBinding() is Binding defaultDinding)
{
targetObject.Bind(ParameterProperty, defaultDinding);
parameters.Add((dynamic)targetObject.GetValue(ParameterProperty));
}
break;
}
}
}
if (to is string name)
{
Trace.WriteLine(name);
ValueTask<object?> namedTask = mediator.Send(new Content(name, parameters.ToArray()));
if (namedTask is ValueTask<object?> { Result: object result })
{
control.SetValue(targetProperty, result);
}
}
if (to is Type type)
{
ValueTask<object?> typedTask = mediator.Send(new Content(type, parameters.ToArray()));
if (typedTask is ValueTask<object?> { Result: object result })
{
control.SetValue(targetProperty, result);
}
}
}
}
}
if (!control.IsLoaded)
{
void HandleLoaded(object? sender, RoutedEventArgs args)
{
control.Loaded -= HandleLoaded;
SetContent();
}
control.Loaded += HandleLoaded;
}
else
{
SetContent();
}
}
}
}
}
return default;
}
}
+45 -49
View File
@@ -6,7 +6,6 @@ using Mediator;
using Toolkit.Framework.Foundation; using Toolkit.Framework.Foundation;
namespace Toolkit.Framework.Avalonia; namespace Toolkit.Framework.Avalonia;
public class NavigateExtension : TriggerExtension public class NavigateExtension : TriggerExtension
{ {
private static readonly AttachedProperty<IMediator> MediatorProperty = private static readonly AttachedProperty<IMediator> MediatorProperty =
@@ -412,74 +411,71 @@ public class NavigateExtension : TriggerExtension
protected override void OnInvoked(object sender, EventArgs args) protected override void OnInvoked(object sender, EventArgs args)
{ {
if (TargetObject is not null) if (TargetObject is not null && mediatorBinding is not null)
{ {
if (mediatorBinding is not null) TargetObject.Bind(MediatorProperty, mediatorBinding);
if (TargetObject.GetValue(MediatorProperty) is IMediator mediator)
{ {
TargetObject.Bind(MediatorProperty, mediatorBinding); if (toBinding is not null)
if (TargetObject.GetValue(MediatorProperty) is IMediator mediator)
{ {
if (toBinding is not null) TargetObject.Bind(ToProperty, toBinding);
if (TargetObject.GetValue(ToProperty) is { } to)
{ {
TargetObject.Bind(ToProperty, toBinding); List<object>? parameters = new();
if (TargetObject.GetValue(ToProperty) is { } to) foreach (object? parameter in this.parameters)
{ {
List<object>? parameters = new(); if (parameter is not null)
foreach (object? parameter in this.parameters)
{ {
if (parameter is not null) switch (parameter)
{ {
switch (parameter) case IParameter keyedParameter:
{ if (keyedParameter.GetValue(TargetObject) is KeyValuePair<string, object> keyValuePair)
case IParameter keyedParameter: {
if (keyedParameter.GetValue(TargetObject) is KeyValuePair<string, object> keyValuePair) parameters.Add(keyValuePair);
{ }
parameters.Add(keyValuePair); break;
}
break;
case IEventParameter eventParameter: case IEventParameter eventParameter:
parameters.AddRange(eventParameter.GetValues(args)); parameters.AddRange(eventParameter.GetValues(args));
break; break;
default: default:
if (parameter.ToBinding() is Binding defaultDinding) if (parameter.ToBinding() is Binding defaultDinding)
{ {
TargetObject.Bind(ParameterProperty, defaultDinding); TargetObject.Bind(ParameterProperty, defaultDinding);
parameters.Add((dynamic)TargetObject.GetValue(ParameterProperty)); parameters.Add((dynamic)TargetObject.GetValue(ParameterProperty));
} }
break; break;
}
} }
} }
}
object? route = null; object? route = null;
if (routeBinding is not null) if (routeBinding is not null)
{
TargetObject.Bind(RouteProperty, routeBinding);
route = TargetObject.GetValue(RouteProperty);
}
if (to is string name)
{
if (toBinding?.StringFormat is string format)
{ {
TargetObject.Bind(RouteProperty, routeBinding); name = string.Format(format, name);
route = TargetObject.GetValue(RouteProperty);
} }
if (to is string name) mediator.Send(new Navigate(name, parameters.ToArray()) { Route = route });
{ }
if (toBinding?.StringFormat is string format)
{
name = string.Format(format, name);
}
mediator.Send(new Navigate(name, parameters.ToArray()) { Route = route }); if (to is Type type)
} {
mediator.Send(new Navigate(type, parameters.ToArray()) { Route = route });
if (to is Type type)
{
mediator.Send(new Navigate(type, parameters.ToArray()) { Route = route });
}
} }
} }
} }
base.OnInvoked(sender, args);
} }
base.OnInvoked(sender, args);
} }
} }
} }
@@ -37,39 +37,35 @@ public class NavigationRouteExtension : MarkupExtension
{ {
if (!TryGetBinding(control, out object? binding)) if (!TryGetBinding(control, out object? binding))
{ {
void HandleDataContextChanged(object? sender, EventArgs args) void AddRoute(TemplatedControl control)
{ {
if (TryGetBinding(control, out binding)) if (mediatorBinding is not null)
{ {
control.Loaded -= HandleLoaded; control.Bind(MediatorProperty, mediatorBinding);
if (mediatorBinding is not null) if (control.GetValue(MediatorProperty) is IMediator mediator)
{ {
control.Bind(MediatorProperty, mediatorBinding); mediator.Send(new NavigationRoute(name, control));
if (control.GetValue(MediatorProperty) is IMediator mediator) control.ClearValue(MediatorProperty);
{
mediator.Send(new NavigationRoute(name, control));
control.ClearValue(MediatorProperty);
}
} }
} }
} }
control.DataContextChanged += HandleDataContextChanged; void HandleDataContextChanged(object? sender, EventArgs args)
{
control.Loaded -= HandleLoaded;
if (TryGetBinding(control, out binding))
{
AddRoute(control);
}
}
control.DataContextChanged += HandleDataContextChanged;
void HandleLoaded(object? sender, RoutedEventArgs args) void HandleLoaded(object? sender, RoutedEventArgs args)
{ {
control.Loaded -= HandleLoaded; control.Loaded -= HandleLoaded;
if (TryGetBinding(control, out binding)) if (TryGetBinding(control, out binding))
{ {
if (mediatorBinding is not null) AddRoute(control);
{
control.Bind(MediatorProperty, mediatorBinding);
if (control.GetValue(MediatorProperty) is IMediator mediator)
{
mediator.Send(new NavigationRoute(name, control));
control.ClearValue(MediatorProperty);
}
}
} }
} }
@@ -31,7 +31,6 @@ public class TriggerExtension : MarkupExtension
if (TargetObject is not null) if (TargetObject is not null)
{ {
string? targetName = target.TargetProperty as string; string? targetName = target.TargetProperty as string;
TargetInvoke = target.TargetProperty; TargetInvoke = target.TargetProperty;
OnAttached(serviceProvider); OnAttached(serviceProvider);
@@ -59,7 +58,7 @@ public class TriggerExtension : MarkupExtension
} }
} }
return null; return default;
} }
protected virtual void OnAttached(IServiceProvider serviceProvider) protected virtual void OnAttached(IServiceProvider serviceProvider)
@@ -9,23 +9,23 @@ public class NavigateHandler : IRequestHandler<Navigate>
{ {
private readonly INavigationRouteDescriptorCollection descriptors; private readonly INavigationRouteDescriptorCollection descriptors;
private readonly IMediator mediator; private readonly IMediator mediator;
private readonly INamedDataTemplateFactory namedDataTemplateFactory; private readonly INamedContentTemplateFactory namedContentTemplateFactory;
private readonly INamedTemplateFactory namedTemplateFactory; private readonly INamedContentFactory namedContentFactory;
private readonly ITemplateFactory templateFactory; private readonly IContentTemplateFactory contentTemplateFactory;
private readonly ITypedDataTemplateFactory typedDataTemplateFactory; private readonly ITypedContentFactory typedContentFactory;
public NavigateHandler(IMediator mediator, public NavigateHandler(IMediator mediator,
ITemplateFactory templateFactory, IContentTemplateFactory contentTemplateFactory,
INamedTemplateFactory namedTemplateFactory, INamedContentFactory namedContentFactory,
INamedDataTemplateFactory namedDataTemplateFactory, INamedContentTemplateFactory namedContentTemplateFactory,
ITypedDataTemplateFactory typedDataTemplateFactory, ITypedContentFactory typedContentFactory,
INavigationRouteDescriptorCollection descriptors) INavigationRouteDescriptorCollection descriptors)
{ {
this.mediator = mediator; this.mediator = mediator;
this.templateFactory = templateFactory; this.contentTemplateFactory = contentTemplateFactory;
this.namedTemplateFactory = namedTemplateFactory; this.namedContentFactory = namedContentFactory;
this.namedDataTemplateFactory = namedDataTemplateFactory; this.namedContentTemplateFactory = namedContentTemplateFactory;
this.typedDataTemplateFactory = typedDataTemplateFactory; this.typedContentFactory = typedContentFactory;
this.descriptors = descriptors; this.descriptors = descriptors;
} }
@@ -54,14 +54,14 @@ public class NavigateHandler : IRequestHandler<Navigate>
if (request.Name is { Length: > 0 } name) if (request.Name is { Length: > 0 } name)
{ {
content = namedDataTemplateFactory.Create(name, parameters.ToArray()); content = namedContentFactory.Create(name, parameters.ToArray());
template = namedTemplateFactory.Create(name); template = namedContentTemplateFactory.Create(name);
} }
if (request.Type is Type type) if (request.Type is Type type)
{ {
content = typedDataTemplateFactory.Create(type, parameters.ToArray()); content = typedContentFactory.Create(type, parameters.ToArray());
template = templateFactory.Create(content); template = contentTemplateFactory.Create(content);
} }
if (template is not null) if (template is not null)
+24
View File
@@ -0,0 +1,24 @@
using Mediator;
namespace Toolkit.Framework.Foundation;
public record Content : IRequest<object?>
{
public Content(string name, params object?[] parameters)
{
Name = name;
Parameters = parameters;
}
public Content(Type type, params object?[] parameters)
{
Type = type;
Parameters = parameters;
}
public Type? Type { get; }
public string? Name { get; }
public object?[] Parameters { get; }
}
@@ -0,0 +1,23 @@
using Microsoft.Extensions.DependencyInjection;
using System.Collections.ObjectModel;
namespace Toolkit.Framework.Foundation;
public class ContentTemplateBuilder : IContentTemplateBuilder
{
private readonly List<IContentTemplateDescriptor> descriptors = new();
public IReadOnlyCollection<IContentTemplateDescriptor> Descriptors => new ReadOnlyCollection<IContentTemplateDescriptor>(descriptors);
public IContentTemplateBuilder Add<TViewModel, TView>(string name, ServiceLifetime lifetime = ServiceLifetime.Transient)
{
descriptors.Add(new ContentTemplateDescriptor(typeof(TViewModel), typeof(TView), name, lifetime));
return this;
}
public IContentTemplateBuilder Add<TViewModel, TView>(ServiceLifetime lifetime = ServiceLifetime.Transient)
{
descriptors.Add(new ContentTemplateDescriptor(typeof(TViewModel), typeof(TView), null, lifetime));
return this;
}
}
@@ -2,9 +2,9 @@
namespace Toolkit.Framework.Foundation; namespace Toolkit.Framework.Foundation;
public class TemplateDescriptor : ITemplateDescriptor public class ContentTemplateDescriptor : IContentTemplateDescriptor
{ {
public TemplateDescriptor(Type dataType, public ContentTemplateDescriptor(Type dataType,
Type templateType, Type templateType,
string? name = null, string? name = null,
ServiceLifetime lifetime = ServiceLifetime.Transient) ServiceLifetime lifetime = ServiceLifetime.Transient)
@@ -0,0 +1,41 @@
namespace Toolkit.Framework.Foundation;
public class ContentTemplateDescriptorProvider : IContentTemplateDescriptorProvider
{
private readonly IReadOnlyCollection<IContentTemplateDescriptor> descriptors;
public ContentTemplateDescriptorProvider(IReadOnlyCollection<IContentTemplateDescriptor> descriptors)
{
this.descriptors = descriptors;
}
public IContentTemplateDescriptor? Get(string name)
{
if (descriptors.FirstOrDefault(x => x.Name == name) is IContentTemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
public IContentTemplateDescriptor? Get(Type type)
{
if (descriptors.FirstOrDefault(x => x.ContentType == type) is IContentTemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
public IContentTemplateDescriptor? Get<T>()
{
if (descriptors.FirstOrDefault(x => x.ContentType == typeof(T)) is IContentTemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
}
@@ -2,14 +2,14 @@
namespace Toolkit.Framework.Foundation; namespace Toolkit.Framework.Foundation;
public class TemplateFactory : ITemplateFactory public class ContentTemplateFactory : IContentTemplateFactory
{ {
private readonly Dictionary<object, object> cache = new(); private readonly Dictionary<object, object> cache = new();
private readonly ITemplateDescriptorProvider provider; private readonly IContentTemplateDescriptorProvider provider;
private readonly IServiceFactory serviceFactory; private readonly IServiceFactory serviceFactory;
public TemplateFactory(ITemplateDescriptorProvider provider, public ContentTemplateFactory(IContentTemplateDescriptorProvider provider,
IServiceFactory serviceFactory) IServiceFactory serviceFactory)
{ {
this.provider = provider; this.provider = provider;
@@ -28,7 +28,7 @@ public class TemplateFactory : ITemplateFactory
return template; return template;
} }
if (provider.Get(data.GetType()) is ITemplateDescriptor descriptor) if (provider.Get(data.GetType()) is IContentTemplateDescriptor descriptor)
{ {
template = serviceFactory.Create(descriptor.TemplateType); template = serviceFactory.Create(descriptor.TemplateType);
if (template is ICache cache) if (template is ICache cache)
@@ -0,0 +1,12 @@
using Microsoft.Extensions.DependencyInjection;
namespace Toolkit.Framework.Foundation;
public interface IContentTemplateBuilder
{
IReadOnlyCollection<IContentTemplateDescriptor> Descriptors { get; }
IContentTemplateBuilder Add<TViewModel, TView>(string name, ServiceLifetime lifetime = ServiceLifetime.Transient);
IContentTemplateBuilder Add<TViewModel, TView>(ServiceLifetime lifetime = ServiceLifetime.Transient);
}
@@ -2,7 +2,7 @@
namespace Toolkit.Framework.Foundation; namespace Toolkit.Framework.Foundation;
public interface ITemplateDescriptor public interface IContentTemplateDescriptor
{ {
Type ContentType { get; } Type ContentType { get; }
@@ -0,0 +1,10 @@
namespace Toolkit.Framework.Foundation;
public interface IContentTemplateDescriptorProvider
{
IContentTemplateDescriptor? Get(string name);
IContentTemplateDescriptor? Get(Type type);
IContentTemplateDescriptor? Get<T>();
}
@@ -0,0 +1,8 @@
using System.Diagnostics.CodeAnalysis;
namespace Toolkit.Framework.Foundation;
public interface IContentTemplateFactory
{
object? Create([MaybeNull] object? content);
}
@@ -1,5 +1,5 @@
namespace Toolkit.Framework.Foundation; namespace Toolkit.Framework.Foundation;
public interface ITemplateSelector public interface IContentTemplateSelector
{ {
} }
@@ -1,6 +1,6 @@
namespace Toolkit.Framework.Foundation; namespace Toolkit.Framework.Foundation;
public interface INamedTemplateFactory public interface INamedContentTemplateFactory
{ {
object? Create(string name); object? Create(string name);
} }
@@ -0,0 +1,6 @@
namespace Toolkit.Framework.Foundation;
public interface INamedContentFactory
{
object? Create(string name, params object?[] parameters);
}
@@ -0,0 +1,6 @@
namespace Toolkit.Framework.Foundation;
public interface ITypedContentFactory
{
object? Create(Type type, params object?[] parameters);
}
@@ -1,13 +1,13 @@
namespace Toolkit.Framework.Foundation; namespace Toolkit.Framework.Foundation;
public class NamedDataTemplateFactory : INamedDataTemplateFactory public class NamedContentFactory : INamedContentFactory
{ {
private readonly Dictionary<string, object> cache = new(); private readonly Dictionary<string, object> cache = new();
private readonly IReadOnlyCollection<ITemplateDescriptor> descriptors; private readonly IReadOnlyCollection<IContentTemplateDescriptor> descriptors;
private readonly IServiceFactory serviceFactory; private readonly IServiceFactory serviceFactory;
public NamedDataTemplateFactory(IReadOnlyCollection<ITemplateDescriptor> descriptors, public NamedContentFactory(IReadOnlyCollection<IContentTemplateDescriptor> descriptors,
IServiceFactory serviceFactory) IServiceFactory serviceFactory)
{ {
this.descriptors = descriptors; this.descriptors = descriptors;
@@ -21,7 +21,7 @@ public class NamedDataTemplateFactory : INamedDataTemplateFactory
return data; return data;
} }
if (descriptors.FirstOrDefault(x => x.Name == name) is ITemplateDescriptor descriptor) if (descriptors.FirstOrDefault(x => x.Name == name) is IContentTemplateDescriptor descriptor)
{ {
data = parameters is { Length: > 0 } ? serviceFactory.Create<object>(descriptor.ContentType, parameters) : serviceFactory.Create(descriptor.ContentType); data = parameters is { Length: > 0 } ? serviceFactory.Create<object>(descriptor.ContentType, parameters) : serviceFactory.Create(descriptor.ContentType);
if (data is ICache cache) if (data is ICache cache)
@@ -1,13 +1,13 @@
namespace Toolkit.Framework.Foundation; namespace Toolkit.Framework.Foundation;
public class NamedTemplateFactory : INamedTemplateFactory public class NamedContentTemplateFactory : INamedContentTemplateFactory
{ {
private readonly Dictionary<string, object> cache = new(); private readonly Dictionary<string, object> cache = new();
private readonly ITemplateDescriptorProvider provider; private readonly IContentTemplateDescriptorProvider provider;
private readonly IServiceFactory serviceFactory; private readonly IServiceFactory serviceFactory;
public NamedTemplateFactory(ITemplateDescriptorProvider provider, public NamedContentTemplateFactory(IContentTemplateDescriptorProvider provider,
IServiceFactory serviceFactory) IServiceFactory serviceFactory)
{ {
this.provider = provider; this.provider = provider;
@@ -21,7 +21,7 @@ public class NamedTemplateFactory : INamedTemplateFactory
return view; return view;
} }
if (provider.Get(name) is ITemplateDescriptor descriptor) if (provider.Get(name) is IContentTemplateDescriptor descriptor)
{ {
view = serviceFactory.Create(descriptor.TemplateType); view = serviceFactory.Create(descriptor.TemplateType);
if (view is ICache cache) if (view is ICache cache)
@@ -1,13 +1,13 @@
namespace Toolkit.Framework.Foundation; namespace Toolkit.Framework.Foundation;
public class TypedDataTemplateFactory : ITypedDataTemplateFactory public class TypedContentFactory : ITypedContentFactory
{ {
private readonly Dictionary<Type, object> cache = new(); private readonly Dictionary<Type, object> cache = new();
private readonly IReadOnlyCollection<ITemplateDescriptor> descriptors; private readonly IReadOnlyCollection<IContentTemplateDescriptor> descriptors;
private readonly IServiceFactory serviceFactory; private readonly IServiceFactory serviceFactory;
public TypedDataTemplateFactory(IReadOnlyCollection<ITemplateDescriptor> descriptors, public TypedContentFactory(IReadOnlyCollection<IContentTemplateDescriptor> descriptors,
IServiceFactory serviceFactory) IServiceFactory serviceFactory)
{ {
this.descriptors = descriptors; this.descriptors = descriptors;
@@ -21,7 +21,7 @@ public class TypedDataTemplateFactory : ITypedDataTemplateFactory
return data; return data;
} }
if (descriptors.FirstOrDefault(x => x.ContentType == type) is ITemplateDescriptor descriptor) if (descriptors.FirstOrDefault(x => x.ContentType == type) is IContentTemplateDescriptor descriptor)
{ {
data = parameters is { Length: > 0 } ? serviceFactory.Create<object>(descriptor.ContentType, parameters) : serviceFactory.Create(descriptor.ContentType); data = parameters is { Length: > 0 } ? serviceFactory.Create<object>(descriptor.ContentType, parameters) : serviceFactory.Create(descriptor.ContentType);
if (data is ICache cache) if (data is ICache cache)
@@ -22,7 +22,5 @@ public record Navigate : IRequest
public string? Name { get; } public string? Name { get; }
public string? FriendlyName { get; init; }
public object?[] Parameters { get; } public object?[] Parameters { get; }
} }
@@ -1,6 +0,0 @@
namespace Toolkit.Framework.Foundation;
public interface INamedDataTemplateFactory
{
object? Create(string name, params object[] parameters);
}
@@ -1,12 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
namespace Toolkit.Framework.Foundation;
public interface ITemplateBuilder
{
IReadOnlyCollection<ITemplateDescriptor> Descriptors { get; }
ITemplateBuilder Add<TViewModel, TView>(string name, ServiceLifetime lifetime = ServiceLifetime.Transient);
ITemplateBuilder Add<TViewModel, TView>(ServiceLifetime lifetime = ServiceLifetime.Transient);
}
@@ -1,10 +0,0 @@
namespace Toolkit.Framework.Foundation;
public interface ITemplateDescriptorProvider
{
ITemplateDescriptor? Get(string name);
ITemplateDescriptor? Get(Type type);
ITemplateDescriptor? Get<T>();
}
@@ -1,8 +0,0 @@
using System.Diagnostics.CodeAnalysis;
namespace Toolkit.Framework.Foundation;
public interface ITemplateFactory
{
object? Create([MaybeNull] object? data);
}
@@ -1,6 +0,0 @@
namespace Toolkit.Framework.Foundation;
public interface ITypedDataTemplateFactory
{
object? Create(Type type, params object[] parameters);
}
@@ -1,23 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using System.Collections.ObjectModel;
namespace Toolkit.Framework.Foundation;
public class TemplateBuilder : ITemplateBuilder
{
private readonly List<ITemplateDescriptor> descriptors = new();
public IReadOnlyCollection<ITemplateDescriptor> Descriptors => new ReadOnlyCollection<ITemplateDescriptor>(descriptors);
public ITemplateBuilder Add<TViewModel, TView>(string name, ServiceLifetime lifetime = ServiceLifetime.Transient)
{
descriptors.Add(new TemplateDescriptor(typeof(TViewModel), typeof(TView), name, lifetime));
return this;
}
public ITemplateBuilder Add<TViewModel, TView>(ServiceLifetime lifetime = ServiceLifetime.Transient)
{
descriptors.Add(new TemplateDescriptor(typeof(TViewModel), typeof(TView), null, lifetime));
return this;
}
}
@@ -1,41 +0,0 @@
namespace Toolkit.Framework.Foundation;
public class TemplateDescriptorProvider : ITemplateDescriptorProvider
{
private readonly IReadOnlyCollection<ITemplateDescriptor> descriptors;
public TemplateDescriptorProvider(IReadOnlyCollection<ITemplateDescriptor> descriptors)
{
this.descriptors = descriptors;
}
public ITemplateDescriptor? Get(string name)
{
if (descriptors.FirstOrDefault(x => x.Name == name) is ITemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
public ITemplateDescriptor? Get(Type type)
{
if (descriptors.FirstOrDefault(x => x.ContentType == type) is ITemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
public ITemplateDescriptor? Get<T>()
{
if (descriptors.FirstOrDefault(x => x.ContentType == typeof(T)) is ITemplateDescriptor descriptor)
{
return descriptor;
}
return null;
}
}