diff --git a/Toolkit.Foundation.Avalonia/Extensions/EventArgsExtensions.cs b/Toolkit.Foundation.Avalonia/Extensions/EventArgsExtensions.cs new file mode 100644 index 0000000..82376d0 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Extensions/EventArgsExtensions.cs @@ -0,0 +1,26 @@ +using Avalonia; +using Avalonia.Data.Converters; +using System.Globalization; + +namespace Toolkit.Foundation.Avalonia +{ + + public static class EventArgsExtensions + { + public static dynamic? GetEventArguments(this EventArgs args, string? path, IValueConverter? converter, object? converterParameter) + { + return !string.IsNullOrWhiteSpace(path) ? GetEventArgsPropertyPathValue(args, path) : converter is not null ? converter.Convert(args, typeof(object), converterParameter, CultureInfo.CurrentCulture) : (dynamic)args; + } + + private static object GetEventArgsPropertyPathValue(object args, string path) + { + object? value = args; + if (path is { }) + { + value = PropertyPathHelper.GetValue(args, path); + } + + return value; + } + } +} diff --git a/Toolkit.Foundation.Avalonia/Extensions/MarkupExtensions.cs b/Toolkit.Foundation.Avalonia/Extensions/MarkupExtensions.cs new file mode 100644 index 0000000..1ae3dc7 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Extensions/MarkupExtensions.cs @@ -0,0 +1,17 @@ +using Avalonia.Data; + +namespace Toolkit.Foundation.Avalonia +{ + public static class MarkupExtensions + { + public static Binding? ToBinding(this object value) + { + if (value is Binding) + { + return value as Binding; + } + + return new Binding { Mode = BindingMode.OneWay, Source = value }; + } + } +} diff --git a/Toolkit.Foundation.Avalonia/Extensions/PropertyPathHelper..cs b/Toolkit.Foundation.Avalonia/Extensions/PropertyPathHelper..cs new file mode 100644 index 0000000..c127a92 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Extensions/PropertyPathHelper..cs @@ -0,0 +1,28 @@ +using Avalonia; +using Avalonia.Data; + +namespace Toolkit.Foundation.Avalonia +{ + public static class PropertyPathHelper + { + private static readonly Dummy dummy = new(); + + public static object GetValue(object args, string path) + { + Binding binding = new(path) + { + Mode = BindingMode.OneTime, + Source = args + }; + + dummy.Bind(Dummy.ValueProperty, binding); + return dummy.GetValue(Dummy.ValueProperty); + } + + private class Dummy : AvaloniaObject + { + public static readonly StyledProperty ValueProperty = + AvaloniaProperty.Register("Value"); + } + } +} diff --git a/Toolkit.Foundation.Avalonia/Markups/CompositeExtension.cs b/Toolkit.Foundation.Avalonia/Markups/CompositeExtension.cs new file mode 100644 index 0000000..1b01e49 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Markups/CompositeExtension.cs @@ -0,0 +1,322 @@ +using Avalonia.Markup.Xaml; +using Kromek.Framework.Avalonia; + +namespace Toolkit.Foundation.Avalonia +{ + public class CompositeExtension : TriggerExtension + { + [ConstructorArgument(nameof(Triggers))] + public TriggerCollection Triggers { get; } = new TriggerCollection(); + + public CompositeExtension(object args0) + { + Triggers.Add(args0); + } + + public CompositeExtension(object args0, + object args1) + { + Triggers.Add(args0); + Triggers.Add(args1); + } + + public CompositeExtension(object args0, + object args1, + object args2) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + } + + public CompositeExtension(object args0, + object args1, + object args2, + object args3) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + } + + public CompositeExtension(object args0, + object args1, + object args2, + object args3, + object args4) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + } + + public CompositeExtension(object args0, + object args1, + object args2, + object args3, + object args4, + object args5) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + } + + public CompositeExtension(object args0, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + } + + public CompositeExtension(object args0, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + } + + public CompositeExtension(object args0, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + Triggers.Add(args8); + } + + public CompositeExtension(object args0, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + Triggers.Add(args8); + Triggers.Add(args9); + } + + public CompositeExtension(object args0, object args1, object args2, object args3, object args4, + object args5, object args6, object args7, object args8, object args9, object args10) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + Triggers.Add(args8); + Triggers.Add(args9); + Triggers.Add(args10); + } + + public CompositeExtension(object args0, object args1, object args2, object args3, object args4, + object args5, object args6, object args7, object args8, object args9, object args10, object args11) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + Triggers.Add(args8); + Triggers.Add(args9); + Triggers.Add(args10); + Triggers.Add(args11); + } + + public CompositeExtension(object args0, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9, + object args10, + object args11, + object args12) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + Triggers.Add(args8); + Triggers.Add(args9); + Triggers.Add(args10); + Triggers.Add(args11); + Triggers.Add(args12); + } + + public CompositeExtension(object args0, + 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) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + Triggers.Add(args8); + Triggers.Add(args9); + Triggers.Add(args10); + Triggers.Add(args11); + Triggers.Add(args12); + Triggers.Add(args13); + } + + public CompositeExtension(object args0, + 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) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + Triggers.Add(args8); + Triggers.Add(args9); + Triggers.Add(args10); + Triggers.Add(args11); + Triggers.Add(args12); + Triggers.Add(args13); + Triggers.Add(args14); + } + + public CompositeExtension(object args0, + 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) + { + Triggers.Add(args0); + Triggers.Add(args1); + Triggers.Add(args2); + Triggers.Add(args3); + Triggers.Add(args4); + Triggers.Add(args5); + Triggers.Add(args6); + Triggers.Add(args7); + Triggers.Add(args8); + Triggers.Add(args9); + Triggers.Add(args10); + Triggers.Add(args11); + Triggers.Add(args12); + Triggers.Add(args13); + Triggers.Add(args14); + Triggers.Add(args15); + } + + protected override void OnInvoked(object sender, EventArgs args) + { + foreach (Delegate? trigger in Triggers) + { + trigger.Method.Invoke(trigger.Target, new object[] { sender, args }); + } + + base.OnInvoked(sender, args); + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation.Avalonia/Markups/EventParameterExtension.cs b/Toolkit.Foundation.Avalonia/Markups/EventParameterExtension.cs new file mode 100644 index 0000000..09fb0c5 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Markups/EventParameterExtension.cs @@ -0,0 +1,65 @@ +using Avalonia.Data.Converters; +using Avalonia.Markup.Xaml; + +namespace Toolkit.Foundation.Avalonia +{ + public class EventParameterExtension : MarkupExtension, IEventParameter + { + private readonly IValueConverter? converter; + + private readonly object? converterParameter; + + private readonly string? key; + private readonly string? path; + + public EventParameterExtension() + { + + } + + public EventParameterExtension(string key, string path) + { + this.key = key; + this.path = path; + } + + public EventParameterExtension(string path) + { + this.path = path; + } + + public EventParameterExtension(IValueConverter? converter = null, object? converterParameter = null) + { + this.converter = converter; + this.converterParameter = converterParameter; + } + + public List GetValues(EventArgs args) + { + List? parameters = new(); + + dynamic? arguments = args.GetEventArguments(path, converter, converterParameter); + if (arguments is not null) + { + if (arguments is ICollection collection) + { + foreach (object? argument in collection) + { + parameters.Add(key is not null ? new KeyValuePair(key, (dynamic)argument) : argument); + } + } + else + { + parameters.Add(key is not null ? new KeyValuePair(key, arguments) : arguments); + } + } + + return parameters; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation.Avalonia/Markups/InvokeExtension.cs b/Toolkit.Foundation.Avalonia/Markups/InvokeExtension.cs new file mode 100644 index 0000000..b3f2f0f --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Markups/InvokeExtension.cs @@ -0,0 +1,424 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Data; +using Avalonia.Markup.Xaml; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; + +namespace Toolkit.Foundation.Avalonia +{ + public class InvokeExtension : TriggerExtension + { + private static readonly AvaloniaProperty TargetProperty = + AvaloniaProperty.RegisterAttached("Target"); + + private readonly object path; + private readonly List parameters = new(); + + public InvokeExtension(object path) + { + this.path = path; + } + + public InvokeExtension(object path, + object args1) + { + this.path = path; + + parameters.Add(args1 is not MarkupExtension ? args1.ToBinding() : args1); + } + + public InvokeExtension(object path, + object args1, + object args2) + { + this.path = path; + + parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding()); + parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding()); + } + + public InvokeExtension(object path, + object args1, + object args2, + object args3) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4, + object args5) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9, + object args10) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9, + object args10, + object args11) + { + this.path = path; + + 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 InvokeExtension(object path, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9, + object args10, + object args11, + object args12) + { + this.path = path; + + 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 InvokeExtension(object path, + 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) + { + this.path = path; + + 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 InvokeExtension(object path, + 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) + { + this.path = path; + + 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 InvokeExtension(object path, + 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) + { + this.path = path; + + 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()); + } + + protected override void OnInvoked(object sender, EventArgs args) + { + if (sender is AvaloniaObject avaloniaObject) + { + CreaterHandler(avaloniaObject, args); + } + } + + private void CreaterHandler(AvaloniaObject sender, EventArgs args) + { + if (TryGetInvoke(sender, out (object? Target, MethodInfo? MethodInfo) invoker)) + { + if (invoker.Target is object target) + { + if (invoker.MethodInfo is MethodInfo methodInfo) + { + ParameterInfo[] parameterInfo = methodInfo.GetParameters(); + List parameters = new(); + + foreach (object? parameter in this.parameters) + { + switch (parameter) + { + //case IParameter keyedParameter: + // BindingOperations.SetBinding(sender, ParameterProperty, parameter.ToBinding()); + // parameters.Add(new KeyValuePair(keyedParameter.Key, (dynamic)sender.GetValue(ParameterProperty))); + // break; + //case IEventParameter eventParameter: + // parameters.AddRange(eventParameter.GetParameters(args)); + // break; + //default: + // BindingOperations.SetBinding(sender, ParameterProperty, parameter.ToBinding()); + // parameters.Add((dynamic)sender.GetValue(ParameterProperty)); + // break; + } + } + + methodInfo.Invoke(target, parameters.Any() ? parameters.ToArray() : parameterInfo.Length > 0 ? new object?[] { null } : Array.Empty()); + } + } + } + } + + private bool TryGetInvoke(AvaloniaObject sender, [AllowNull] out (object?, MethodInfo?) invoker) + { + if (path is Binding binding) + { + sender.Bind(TargetProperty, binding); + if (sender.GetValue(TargetProperty) is Action action) + { + invoker = new(action.Target, action.Method); + return true; + } + } + + if (path is string name) + { + if (sender.GetValue(StyledElement.DataContextProperty) is object dataContext) + { + if (dataContext.GetType().GetMethod(name, BindingFlags.Public | BindingFlags.Instance) is MethodInfo methodInfo) + { + invoker = new(dataContext, methodInfo); + return true; + } + } + } + + invoker = default; + return false; + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation.Avalonia/Markups/NavigateExtension.cs b/Toolkit.Foundation.Avalonia/Markups/NavigateExtension.cs new file mode 100644 index 0000000..02eac98 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Markups/NavigateExtension.cs @@ -0,0 +1,488 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Data; +using Avalonia.Markup.Xaml; +using Kromek.Framework.Core.Extensions; +using Kromek.Framework.Core; +using System; +using System.Collections.Generic; + +namespace Toolkit.Foundation.Avalonia +{ + public class NavigateExtension : TriggerExtension + { + private static readonly AttachedProperty NavigationRouterProperty = + AvaloniaProperty.RegisterAttached("NavigationRouter"); + + private static readonly AttachedProperty ParameterProperty = + AvaloniaProperty.RegisterAttached("Parameter"); + + private static readonly AvaloniaProperty RouteProperty = + AvaloniaProperty.RegisterAttached("Route"); + + private static readonly AvaloniaProperty ToProperty = + AvaloniaProperty.RegisterAttached("To"); + + private readonly Binding? navigationRouterBinding; + private readonly List parameters = new(); + private readonly Binding? toBinding; + private object? route; + private Binding? routeBinding; + + public NavigateExtension(object navigationRouter, + object to) + { + navigationRouterBinding = navigationRouter.ToBinding(); + this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding(); + } + + public NavigateExtension(object navigationRouter, + object to, + object args1) + { + navigationRouterBinding = navigationRouter.ToBinding(); + this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding(); + + parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding()); + } + + public NavigateExtension(object navigationRouter, + object to, + object args1, + object args2) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3, + object args4) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3, + object args4, + object args5) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9, + object args10) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + object to, + object args1, + object args2, + object args3, + object args4, + object args5, + object args6, + object args7, + object args8, + object args9, + object args10, + object args11) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + 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) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + 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) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + 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) + { + navigationRouterBinding = navigationRouter.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 NavigateExtension(object navigationRouter, + 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) + { + navigationRouterBinding = navigationRouter.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 object? Route + { + get + { + return route; + } + set + { + route = value; + if (route is not null) + { + routeBinding = route.ToBinding(); + } + } + + } + + protected override void OnInvoked(object sender, EventArgs args) + { + if (TargetObject is not null) + { + if (navigationRouterBinding is not null) + { + TargetObject.Bind(NavigationRouterProperty, navigationRouterBinding); + if (TargetObject.GetValue(NavigationRouterProperty) is INavigationRouter router) + { + if (toBinding is not null) + { + TargetObject.Bind(ToProperty, toBinding); + if (TargetObject.GetValue(ToProperty) is { } to) + { + List? parameters = new(); + foreach (object? parameter in this.parameters) + { + if (parameter is not null) + { + switch (parameter) + { + case IParameter keyedParameter: + if (keyedParameter.GetValue(TargetObject) is KeyValuePair keyValuePair) + { + parameters.Add(keyValuePair); + } + 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; + } + } + } + + 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) + { + name = string.Format(format, name); + } + + router.Navigate(new Navigate(name, parameters.ToArray()) { Route = route }); + } + + if (to is Type type) + { + router.Navigate(new Navigate(type, parameters.ToArray()) { Route = route }); + } + } + } + + } + + base.OnInvoked(sender, args); + } + } + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation.Avalonia/Markups/NavigationRouteExtension.cs b/Toolkit.Foundation.Avalonia/Markups/NavigationRouteExtension.cs new file mode 100644 index 0000000..aa8c02e --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Markups/NavigationRouteExtension.cs @@ -0,0 +1,89 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Data; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; + +namespace Toolkit.Foundation.Avalonia +{ + public class NavigationRouteExtension : MarkupExtension + { + private static readonly AttachedProperty RouteProperty = + AvaloniaProperty.RegisterAttached("Route"); + + private readonly string name; + private readonly Binding? routeBinding; + + public NavigationRouteExtension(object route, string name) + { + routeBinding = route is Binding toBinding ? toBinding : route.ToBinding(); + this.name = name; + } + + private bool TryGetBinding(AvaloniaObject sender, out object? binding) + { + binding = sender.GetValue(StyledElement.DataContextProperty); + return binding is not null; + } + + public override object? ProvideValue(IServiceProvider serviceProvider) + { + if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target) + { + if (target.TargetObject is TemplatedControl control) + { + if (routeBinding is not null) + { + if (!TryGetBinding(control, out object? binding)) + { + void HandleDataContextChanged(object? sender, EventArgs args) + { + if (TryGetBinding(control, out binding)) + { + control.Loaded -= HandleLoaded; + control.Bind(RouteProperty, routeBinding); + + if (control?.GetValue(RouteProperty) is INavigationRouter router) + { + router.Register(name, control); + control.ClearValue(RouteProperty); + } + } + } + + control.DataContextChanged += HandleDataContextChanged; + + void HandleLoaded(object? sender, RoutedEventArgs args) + { + control.Loaded -= HandleLoaded; + if (TryGetBinding(control, out binding)) + { + control.Bind(RouteProperty, routeBinding); + if (control?.GetValue(RouteProperty) is INavigationRouter router) + { + router.Register(name, control); + control.ClearValue(RouteProperty); + } + } + } + + control.Loaded += HandleLoaded; + } + else + { + control.Bind(RouteProperty, routeBinding); + if (control?.GetValue(RouteProperty) is INavigationRouter router) + { + router.Register(name, control); + control.ClearValue(RouteProperty); + } + } + } + } + } + + return null; + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation.Avalonia/Markups/ParameterBindingExtension.cs b/Toolkit.Foundation.Avalonia/Markups/ParameterBindingExtension.cs new file mode 100644 index 0000000..66c6209 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Markups/ParameterBindingExtension.cs @@ -0,0 +1,42 @@ +using Avalonia.Controls; +using Avalonia; +using Avalonia.Data; +using Avalonia.Markup.Xaml; + +namespace Toolkit.Foundation.Avalonia +{ + public class ParameterBindingExtension : MarkupExtension, IParameter + { + private static readonly AttachedProperty ValueProperty = + AvaloniaProperty.RegisterAttached("Value"); + + private readonly Binding? valueBinding; + + public ParameterBindingExtension(string key, object value) + { + Key = key; + valueBinding = value.ToBinding(); + } + + public string? Key { get; } + + public KeyValuePair? GetValue(object target) + { + if (target is AvaloniaObject avaloniaObject) + { + if (valueBinding is not null) + { + avaloniaObject.Bind(ValueProperty, valueBinding); + return new KeyValuePair(Key, (dynamic)avaloniaObject.GetValue(ValueProperty)); + } + } + + return default; + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } + } +} diff --git a/Toolkit.Foundation.Avalonia/Markups/TriggerCollection.cs b/Toolkit.Foundation.Avalonia/Markups/TriggerCollection.cs new file mode 100644 index 0000000..f6213c4 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Markups/TriggerCollection.cs @@ -0,0 +1,15 @@ +using System.Collections.ObjectModel; + +namespace Toolkit.Foundation.Avalonia +{ + public class TriggerCollection : Collection + { + public void Add(object item) + { + if (item is Delegate trigger) + { + base.Add(trigger); + } + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation.Avalonia/Markups/TriggerExtension.cs b/Toolkit.Foundation.Avalonia/Markups/TriggerExtension.cs new file mode 100644 index 0000000..0e664f6 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Markups/TriggerExtension.cs @@ -0,0 +1,76 @@ +using Avalonia; +using Avalonia.Markup.Xaml; +using System; +using System.Reflection; + +namespace Toolkit.Foundation.Avalonia +{ + public class TriggerExtension : MarkupExtension + { + public AvaloniaObject? TargetObject { get; protected set; } + + protected object? TargetInvoke { get; private set; } + + public void Invoke(object sender, EventArgs args) + { + OnInvoked(sender, args); + } + + public override object? ProvideValue(IServiceProvider serviceProvider) + { + if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target) + { + 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) + { + string? targetName = target.TargetProperty as string; + + TargetInvoke = target.TargetProperty; + OnAttached(serviceProvider); + + EventInfo? eventInfo = target.TargetProperty as EventInfo ?? (targetName is not null ? TargetObject.GetType().GetEvent(targetName) : null); + MethodInfo? methodInfo = eventInfo is not null ? null : target.TargetProperty as MethodInfo ?? (targetName is not null ? TargetObject.GetType().GetMethod(targetName) : null); + + MethodInfo invokeMethod = GetType().GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public)!; + if (invokeMethod is null) + { + return this; + } + + if (eventInfo is not null) + { + return Delegate.CreateDelegate(eventInfo.EventHandlerType!, this, invokeMethod); + } + + if (methodInfo is not null) + { + if (methodInfo.GetParameters() is ParameterInfo[] methodParameters && methodParameters is { Length: 2 }) + { + return Delegate.CreateDelegate(methodParameters[1].ParameterType, this, invokeMethod); + } + } + } + } + + return null; + } + + protected virtual void OnAttached(IServiceProvider serviceProvider) + { + + } + + protected virtual void OnInvoked(object sender, EventArgs args) + { + + } + } +} \ No newline at end of file diff --git a/Toolkit.Foundation.Avalonia/Navigation/NavigationRoute.cs b/Toolkit.Foundation.Avalonia/Navigation/NavigationRoute.cs deleted file mode 100644 index 689671f..0000000 --- a/Toolkit.Foundation.Avalonia/Navigation/NavigationRoute.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Avalonia.Controls.Primitives; -using Avalonia.Interactivity; - -namespace Toolkit.Foundation.Avalonia -{ - public class NavigationRoute : INavigationRoute - { - private readonly INavigationRouteDescriptorCollection routes; - - public NavigationRoute(INavigationRouteDescriptorCollection routes) - { - this.routes = routes; - } - - public void Add(string name, object route) - { - if (route is TemplatedControl control) - { - void HandleUnloaded(object? sender, RoutedEventArgs args) - { - if (routes.FirstOrDefault(x => x.Route == sender) is INavigationRouteDescriptor descriptor) - { - routes.Remove(descriptor); - } - } - - control.Unloaded += HandleUnloaded; - } - - if (routes.FirstOrDefault(x => x.Name == name) is INavigationRouteDescriptor descriptor) - { - routes.Remove(descriptor); - } - - routes.Add(new NavigationRouteDescriptor(name, route)); - } - } -} diff --git a/Toolkit.Foundation.Avalonia/Navigation/NavigationRouter.cs b/Toolkit.Foundation.Avalonia/Navigation/NavigationRouter.cs index 5614f5b..5940dc9 100644 --- a/Toolkit.Foundation.Avalonia/Navigation/NavigationRouter.cs +++ b/Toolkit.Foundation.Avalonia/Navigation/NavigationRouter.cs @@ -1,5 +1,6 @@ using Avalonia.Controls; using Avalonia.Controls.Primitives; +using Avalonia.Interactivity; using CommunityToolkit.Mvvm.Messaging; using FluentAvalonia.UI.Controls; @@ -32,15 +33,7 @@ namespace Toolkit.Foundation.Avalonia this.descriptors = descriptors; } - public Task InitializeAsync() - { - messenger.Register(this, (sender, args) => OnNavigate(args)); - messenger.Register(this, (sender, args) => OnNavigateBack(args)); - - return Task.CompletedTask; - } - - private async void OnNavigate(Navigate args) + public async void Navigate(Navigate args) { object? data = null; object? template = null; @@ -115,7 +108,30 @@ namespace Toolkit.Foundation.Avalonia } } - private void OnNavigateBack(NavigateBack args) + public void Register(string name, object route) + { + if (route is TemplatedControl control) + { + void HandleUnloaded(object? sender, RoutedEventArgs args) + { + if (descriptors.FirstOrDefault(x => x.Route == sender) is INavigationRouteDescriptor descriptor) + { + descriptors.Remove(descriptor); + } + } + + control.Unloaded += HandleUnloaded; + } + + if (descriptors.FirstOrDefault(x => x.Name == name) is INavigationRouteDescriptor descriptor) + { + descriptors.Remove(descriptor); + } + + descriptors.Add(new NavigationRouteDescriptor(name, route)); + } + + public void GoBack(NavigateBack args) { if (descriptors.FirstOrDefault(x => args.Route is string { } name && name == x.Name) is NavigationRouteDescriptor descriptor) { diff --git a/Toolkit.Foundation.Avalonia/Templates/TemplateSelector.cs b/Toolkit.Foundation.Avalonia/Templates/TemplateSelector.cs new file mode 100644 index 0000000..b0cb881 --- /dev/null +++ b/Toolkit.Foundation.Avalonia/Templates/TemplateSelector.cs @@ -0,0 +1,37 @@ +using Avalonia.Controls.Templates; +using Avalonia.Controls; + +namespace Toolkit.Foundation.Avalonia +{ + public class TemplateSelector : IDataTemplate, ITemplateSelector + { + private readonly Dictionary dataTracking = new(); + + private readonly ITemplateFactory templateFactory; + + public TemplateSelector(ITemplateFactory templateFactory) + { + this.templateFactory = templateFactory; + } + + public IControl? Build(object? item) + { + if (item is not null) + { + if (dataTracking.TryGetValue(item, out IControl? control)) + { + return control; + } + + return (IControl?)templateFactory.Create(item); + } + + return null; + } + + public bool Match(object? data) + { + return true; + } + } +} diff --git a/Toolkit.Foundation/Navigation/INavigationRoute.cs b/Toolkit.Foundation/Navigation/INavigationRoute.cs deleted file mode 100644 index 2085a4e..0000000 --- a/Toolkit.Foundation/Navigation/INavigationRoute.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Toolkit.Foundation -{ - public interface INavigationRoute - { - void Add(string name, object route); - } -} \ No newline at end of file diff --git a/Toolkit.Foundation/Navigation/INavigationRouter.cs b/Toolkit.Foundation/Navigation/INavigationRouter.cs index e11f7ca..9abf486 100644 --- a/Toolkit.Foundation/Navigation/INavigationRouter.cs +++ b/Toolkit.Foundation/Navigation/INavigationRouter.cs @@ -1,6 +1,9 @@ namespace Toolkit.Foundation { - public interface INavigationRouter : IInitializer + public interface INavigationRouter { + void Navigate(Navigate args); + + void Register(string name, object route); } } \ No newline at end of file diff --git a/Toolkit.Foundation/Navigation/Navigate.cs b/Toolkit.Foundation/Navigation/Navigate.cs index e5278bf..c36006c 100644 --- a/Toolkit.Foundation/Navigation/Navigate.cs +++ b/Toolkit.Foundation/Navigation/Navigate.cs @@ -1,6 +1,4 @@ -using System; - -namespace Toolkit.Foundation +namespace Toolkit.Foundation { public record Navigate {