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.Templates;
using System.Diagnostics;
using Toolkit.Framework.Foundation;
namespace Toolkit.Framework.Avalonia;
public class TemplateSelector : IDataTemplate, ITemplateSelector
public class ContentTemplateSelector : IDataTemplate, IContentTemplateSelector
{
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;
}
@@ -7,22 +7,22 @@ namespace Toolkit.Framework.Avalonia;
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) =>
{
TemplateBuilder? builder = new();
ContentTemplateBuilder? builder = new();
builderDelegate?.Invoke(builder);
serviceCollection.TryAddSingleton(builder.Descriptors);
serviceCollection.TryAddSingleton<ITemplateDescriptorProvider, TemplateDescriptorProvider>();
serviceCollection.TryAddSingleton<ITemplateFactory, TemplateFactory>();
serviceCollection.TryAddSingleton<INamedTemplateFactory, NamedTemplateFactory>();
serviceCollection.TryAddSingleton<ITypedDataTemplateFactory, TypedDataTemplateFactory>();
serviceCollection.TryAddSingleton<INamedDataTemplateFactory, NamedDataTemplateFactory>();
serviceCollection.TryAddSingleton<ITemplateSelector, TemplateSelector>();
serviceCollection.TryAddSingleton<IContentTemplateDescriptorProvider, ContentTemplateDescriptorProvider>();
serviceCollection.TryAddSingleton<IContentTemplateFactory, ContentTemplateFactory>();
serviceCollection.TryAddSingleton<INamedContentFactory, NamedContentFactory>();
serviceCollection.TryAddSingleton<ITypedContentFactory, TypedContentFactory>();
serviceCollection.TryAddSingleton<INamedContentTemplateFactory, NamedContentTemplateFactory>();
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.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;
namespace Toolkit.Framework.Avalonia;
public class NavigateExtension : TriggerExtension
{
private static readonly AttachedProperty<IMediator> MediatorProperty =
@@ -412,74 +411,71 @@ public class NavigateExtension : TriggerExtension
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 (TargetObject.GetValue(MediatorProperty) is IMediator mediator)
if (toBinding is not null)
{
if (toBinding is not null)
TargetObject.Bind(ToProperty, toBinding);
if (TargetObject.GetValue(ToProperty) is { } to)
{
TargetObject.Bind(ToProperty, toBinding);
if (TargetObject.GetValue(ToProperty) is { } to)
List<object>? parameters = new();
foreach (object? parameter in this.parameters)
{
List<object>? parameters = new();
foreach (object? parameter in this.parameters)
if (parameter is not null)
{
if (parameter is not null)
switch (parameter)
{
switch (parameter)
{
case IParameter keyedParameter:
if (keyedParameter.GetValue(TargetObject) is KeyValuePair<string, object> keyValuePair)
{
parameters.Add(keyValuePair);
}
break;
case IParameter keyedParameter:
if (keyedParameter.GetValue(TargetObject) is KeyValuePair<string, object> keyValuePair)
{
parameters.Add(keyValuePair);
}
break;
case IEventParameter eventParameter:
parameters.AddRange(eventParameter.GetValues(args));
break;
case IEventParameter eventParameter:
parameters.AddRange(eventParameter.GetValues(args));
break;
default:
if (parameter.ToBinding() is Binding defaultDinding)
{
TargetObject.Bind(ParameterProperty, defaultDinding);
parameters.Add((dynamic)TargetObject.GetValue(ParameterProperty));
}
break;
}
default:
if (parameter.ToBinding() is Binding defaultDinding)
{
TargetObject.Bind(ParameterProperty, defaultDinding);
parameters.Add((dynamic)TargetObject.GetValue(ParameterProperty));
}
break;
}
}
}
object? route = null;
if (routeBinding is not null)
object? route = 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);
route = TargetObject.GetValue(RouteProperty);
name = string.Format(format, name);
}
if (to is string name)
{
if (toBinding?.StringFormat is string format)
{
name = string.Format(format, name);
}
mediator.Send(new Navigate(name, parameters.ToArray()) { Route = route });
}
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))
{
void HandleDataContextChanged(object? sender, EventArgs args)
void AddRoute(TemplatedControl control)
{
if (TryGetBinding(control, out binding))
if (mediatorBinding is not null)
{
control.Loaded -= HandleLoaded;
if (mediatorBinding is not null)
control.Bind(MediatorProperty, mediatorBinding);
if (control.GetValue(MediatorProperty) is IMediator mediator)
{
control.Bind(MediatorProperty, mediatorBinding);
if (control.GetValue(MediatorProperty) is IMediator mediator)
{
mediator.Send(new NavigationRoute(name, control));
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)
{
control.Loaded -= HandleLoaded;
if (TryGetBinding(control, out binding))
{
if (mediatorBinding is not null)
{
control.Bind(MediatorProperty, mediatorBinding);
if (control.GetValue(MediatorProperty) is IMediator mediator)
{
mediator.Send(new NavigationRoute(name, control));
control.ClearValue(MediatorProperty);
}
}
AddRoute(control);
}
}
@@ -31,7 +31,6 @@ public class TriggerExtension : MarkupExtension
if (TargetObject is not null)
{
string? targetName = target.TargetProperty as string;
TargetInvoke = target.TargetProperty;
OnAttached(serviceProvider);
@@ -59,7 +58,7 @@ public class TriggerExtension : MarkupExtension
}
}
return null;
return default;
}
protected virtual void OnAttached(IServiceProvider serviceProvider)
@@ -9,23 +9,23 @@ public class NavigateHandler : IRequestHandler<Navigate>
{
private readonly INavigationRouteDescriptorCollection descriptors;
private readonly IMediator mediator;
private readonly INamedDataTemplateFactory namedDataTemplateFactory;
private readonly INamedTemplateFactory namedTemplateFactory;
private readonly ITemplateFactory templateFactory;
private readonly ITypedDataTemplateFactory typedDataTemplateFactory;
private readonly INamedContentTemplateFactory namedContentTemplateFactory;
private readonly INamedContentFactory namedContentFactory;
private readonly IContentTemplateFactory contentTemplateFactory;
private readonly ITypedContentFactory typedContentFactory;
public NavigateHandler(IMediator mediator,
ITemplateFactory templateFactory,
INamedTemplateFactory namedTemplateFactory,
INamedDataTemplateFactory namedDataTemplateFactory,
ITypedDataTemplateFactory typedDataTemplateFactory,
IContentTemplateFactory contentTemplateFactory,
INamedContentFactory namedContentFactory,
INamedContentTemplateFactory namedContentTemplateFactory,
ITypedContentFactory typedContentFactory,
INavigationRouteDescriptorCollection descriptors)
{
this.mediator = mediator;
this.templateFactory = templateFactory;
this.namedTemplateFactory = namedTemplateFactory;
this.namedDataTemplateFactory = namedDataTemplateFactory;
this.typedDataTemplateFactory = typedDataTemplateFactory;
this.contentTemplateFactory = contentTemplateFactory;
this.namedContentFactory = namedContentFactory;
this.namedContentTemplateFactory = namedContentTemplateFactory;
this.typedContentFactory = typedContentFactory;
this.descriptors = descriptors;
}
@@ -54,14 +54,14 @@ public class NavigateHandler : IRequestHandler<Navigate>
if (request.Name is { Length: > 0 } name)
{
content = namedDataTemplateFactory.Create(name, parameters.ToArray());
template = namedTemplateFactory.Create(name);
content = namedContentFactory.Create(name, parameters.ToArray());
template = namedContentTemplateFactory.Create(name);
}
if (request.Type is Type type)
{
content = typedDataTemplateFactory.Create(type, parameters.ToArray());
template = templateFactory.Create(content);
content = typedContentFactory.Create(type, parameters.ToArray());
template = contentTemplateFactory.Create(content);
}
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;
public class TemplateDescriptor : ITemplateDescriptor
public class ContentTemplateDescriptor : IContentTemplateDescriptor
{
public TemplateDescriptor(Type dataType,
public ContentTemplateDescriptor(Type dataType,
Type templateType,
string? name = null,
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;
public class TemplateFactory : ITemplateFactory
public class ContentTemplateFactory : IContentTemplateFactory
{
private readonly Dictionary<object, object> cache = new();
private readonly ITemplateDescriptorProvider provider;
private readonly IContentTemplateDescriptorProvider provider;
private readonly IServiceFactory serviceFactory;
public TemplateFactory(ITemplateDescriptorProvider provider,
public ContentTemplateFactory(IContentTemplateDescriptorProvider provider,
IServiceFactory serviceFactory)
{
this.provider = provider;
@@ -28,7 +28,7 @@ public class TemplateFactory : ITemplateFactory
return template;
}
if (provider.Get(data.GetType()) is ITemplateDescriptor descriptor)
if (provider.Get(data.GetType()) is IContentTemplateDescriptor descriptor)
{
template = serviceFactory.Create(descriptor.TemplateType);
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;
public interface ITemplateDescriptor
public interface IContentTemplateDescriptor
{
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;
public interface ITemplateSelector
public interface IContentTemplateSelector
{
}
@@ -1,6 +1,6 @@
namespace Toolkit.Framework.Foundation;
public interface INamedTemplateFactory
public interface INamedContentTemplateFactory
{
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;
public class NamedDataTemplateFactory : INamedDataTemplateFactory
public class NamedContentFactory : INamedContentFactory
{
private readonly Dictionary<string, object> cache = new();
private readonly IReadOnlyCollection<ITemplateDescriptor> descriptors;
private readonly IReadOnlyCollection<IContentTemplateDescriptor> descriptors;
private readonly IServiceFactory serviceFactory;
public NamedDataTemplateFactory(IReadOnlyCollection<ITemplateDescriptor> descriptors,
public NamedContentFactory(IReadOnlyCollection<IContentTemplateDescriptor> descriptors,
IServiceFactory serviceFactory)
{
this.descriptors = descriptors;
@@ -21,7 +21,7 @@ public class NamedDataTemplateFactory : INamedDataTemplateFactory
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);
if (data is ICache cache)
@@ -1,13 +1,13 @@
namespace Toolkit.Framework.Foundation;
public class NamedTemplateFactory : INamedTemplateFactory
public class NamedContentTemplateFactory : INamedContentTemplateFactory
{
private readonly Dictionary<string, object> cache = new();
private readonly ITemplateDescriptorProvider provider;
private readonly IContentTemplateDescriptorProvider provider;
private readonly IServiceFactory serviceFactory;
public NamedTemplateFactory(ITemplateDescriptorProvider provider,
public NamedContentTemplateFactory(IContentTemplateDescriptorProvider provider,
IServiceFactory serviceFactory)
{
this.provider = provider;
@@ -21,7 +21,7 @@ public class NamedTemplateFactory : INamedTemplateFactory
return view;
}
if (provider.Get(name) is ITemplateDescriptor descriptor)
if (provider.Get(name) is IContentTemplateDescriptor descriptor)
{
view = serviceFactory.Create(descriptor.TemplateType);
if (view is ICache cache)
@@ -1,13 +1,13 @@
namespace Toolkit.Framework.Foundation;
public class TypedDataTemplateFactory : ITypedDataTemplateFactory
public class TypedContentFactory : ITypedContentFactory
{
private readonly Dictionary<Type, object> cache = new();
private readonly IReadOnlyCollection<ITemplateDescriptor> descriptors;
private readonly IReadOnlyCollection<IContentTemplateDescriptor> descriptors;
private readonly IServiceFactory serviceFactory;
public TypedDataTemplateFactory(IReadOnlyCollection<ITemplateDescriptor> descriptors,
public TypedContentFactory(IReadOnlyCollection<IContentTemplateDescriptor> descriptors,
IServiceFactory serviceFactory)
{
this.descriptors = descriptors;
@@ -21,7 +21,7 @@ public class TypedDataTemplateFactory : ITypedDataTemplateFactory
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);
if (data is ICache cache)
@@ -22,7 +22,5 @@ public record Navigate : IRequest
public string? Name { get; }
public string? FriendlyName { get; init; }
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;
}
}