From 3e3cf552c9ea33cda5504bd2a8bdb44cf28bc657 Mon Sep 17 00:00:00 2001 From: Dong Bin <14807942+rabbitism@users.noreply.github.com> Date: Sun, 21 Apr 2024 18:26:18 +0800 Subject: [PATCH] Add more overloads for AddHandler/SetValue --- .../Helpers/AvaloniaPropertyExtension.cs | 28 +- .../Helpers/RoutedEventExtension.cs | 158 +++++++++- .../Helpers/AvaloniaPropertyExtensionTest.cs | 12 +- .../Helpers/RoutedEventExtensionTest.cs | 274 +++++++++++++++++- 4 files changed, 457 insertions(+), 15 deletions(-) diff --git a/src/Irihi.Avalonia.Shared.Public/Helpers/AvaloniaPropertyExtension.cs b/src/Irihi.Avalonia.Shared.Public/Helpers/AvaloniaPropertyExtension.cs index 7b02340..e18b1d6 100644 --- a/src/Irihi.Avalonia.Shared.Public/Helpers/AvaloniaPropertyExtension.cs +++ b/src/Irihi.Avalonia.Shared.Public/Helpers/AvaloniaPropertyExtension.cs @@ -6,7 +6,10 @@ namespace Irihi.Avalonia.Shared.Helpers; public static class AvaloniaPropertyExtension { - public static void SetValue(this AvaloniaProperty property, T value, params AvaloniaObject?[] objects) + public static void SetValue( + this AvaloniaProperty property, + T value, + params AvaloniaObject?[] objects) { foreach (var obj in objects) { @@ -14,21 +17,32 @@ public static void SetValue(this AvaloniaProperty property, T value, param } } - public static void SetValue(this AvaloniaProperty property, TValue value, params TItem?[] objects) where TItem: AvaloniaObject + public static void SetValue( + this AvaloniaProperty property, + T value, + IEnumerable objects) + where TControl: AvaloniaObject { foreach (var obj in objects) { obj?.SetValue(property, value); - } + } } - public static void AffectsPseudoClass(this AvaloniaProperty property, string pseudoClass, RoutedEvent? routedEvent = null) + public static void AffectsPseudoClass( + this AvaloniaProperty property, + string pseudoClass, + RoutedEvent? routedEvent = null) where TControl: Control { property.Changed.AddClassHandler((control, args) => {OnPropertyChanged(control, args, pseudoClass, routedEvent); }); } - private static void OnPropertyChanged(TControl control, AvaloniaPropertyChangedEventArgs args, string pseudoClass, RoutedEvent? routedEvent) + private static void OnPropertyChanged( + TControl control, + AvaloniaPropertyChangedEventArgs args, + string pseudoClass, + RoutedEvent? routedEvent) where TControl: Control where TArgs: RoutedEventArgs, new() { @@ -39,7 +53,9 @@ private static void OnPropertyChanged(TControl control, Avaloni } } - public static void AffectsPseudoClass(this AvaloniaProperty property, string pseudoClass, + public static void AffectsPseudoClass( + this AvaloniaProperty property, + string pseudoClass, RoutedEvent? routedEvent = null) where TControl: Control where TArgs: RoutedEventArgs, new() diff --git a/src/Irihi.Avalonia.Shared.Public/Helpers/RoutedEventExtension.cs b/src/Irihi.Avalonia.Shared.Public/Helpers/RoutedEventExtension.cs index 627e139..fc222c4 100644 --- a/src/Irihi.Avalonia.Shared.Public/Helpers/RoutedEventExtension.cs +++ b/src/Irihi.Avalonia.Shared.Public/Helpers/RoutedEventExtension.cs @@ -1,4 +1,3 @@ -using Avalonia.Controls; using Avalonia.Interactivity; using Irihi.Avalonia.Shared.Reactive; @@ -6,7 +5,23 @@ namespace Irihi.Avalonia.Shared.Helpers; public static class RoutedEventExtension { - public static void AddHandler(this RoutedEvent routedEvent, EventHandler handler, params Interactive?[] controls) + public static void AddHandler( + this RoutedEvent routedEvent, + EventHandler handler, + params Interactive?[] controls) + where TArgs : RoutedEventArgs + { + foreach (var t in controls) + { + t?.AddHandler(routedEvent, handler); + } + } + + public static void AddHandler( + this RoutedEvent routedEvent, + EventHandler handler, + params TControl?[] controls) + where TControl: Interactive where TArgs : RoutedEventArgs { foreach (var t in controls) @@ -15,7 +30,8 @@ public static void AddHandler(this RoutedEvent routedEvent, EventH } } - public static void AddHandler(this RoutedEvent routedEvent, + public static void AddHandler( + this RoutedEvent routedEvent, EventHandler handler, RoutingStrategies strategies = RoutingStrategies.Bubble | RoutingStrategies.Direct, bool handledEventsToo = false, @@ -28,7 +44,40 @@ public static void AddHandler(this RoutedEvent routedEvent, } } - public static void RemoveHandler(this RoutedEvent routedEvent, EventHandler handler, params Interactive?[] controls) + public static void AddHandler( + this RoutedEvent routedEvent, + EventHandler handler, + RoutingStrategies strategies = RoutingStrategies.Bubble | RoutingStrategies.Direct, + bool handledEventsToo = false, + params TControl?[] controls) + where TArgs : RoutedEventArgs + where TControl: Interactive + { + foreach (var t in controls) + { + t?.AddHandler(routedEvent, handler, strategies, handledEventsToo); + } + } + + public static void AddHandler( + this RoutedEvent routedEvent, + EventHandler handler, + IEnumerable controls, + RoutingStrategies strategies = RoutingStrategies.Bubble | RoutingStrategies.Direct, + bool handledEventsToo = false) + where TArgs : RoutedEventArgs + where TControl: Interactive + { + foreach (var t in controls) + { + t?.AddHandler(routedEvent, handler, strategies, handledEventsToo); + } + } + + public static void RemoveHandler( + this RoutedEvent routedEvent, + EventHandler handler, + params Interactive?[] controls) where TArgs : RoutedEventArgs { foreach (var t in controls) @@ -36,9 +85,58 @@ public static void RemoveHandler(this RoutedEvent routedEvent, Eve t?.RemoveHandler(routedEvent, handler); } } - - public static IDisposable AddDisposableHandler(this RoutedEvent routedEvent, EventHandler handler, params Interactive?[] controls) + + public static void RemoveHandler( + this RoutedEvent routedEvent, + EventHandler handler, + params TControl?[] controls) + where TArgs : RoutedEventArgs + where TControl: Interactive + { + foreach (var t in controls) + { + t?.RemoveHandler(routedEvent, handler); + } + } + + public static void RemoveHandler( + this RoutedEvent routedEvent, + EventHandler handler, + IEnumerable controls) where TArgs : RoutedEventArgs + where TControl: Interactive + { + foreach (var t in controls) + { + t?.RemoveHandler(routedEvent, handler); + } + } + + public static IDisposable AddDisposableHandler( + this RoutedEvent routedEvent, + EventHandler handler, + params Interactive?[] controls) + where TArgs : RoutedEventArgs + { + var list = new List(controls.Length); + foreach (var t in controls) + { + var disposable = t?.AddDisposableHandler(routedEvent, handler); + if (disposable != null) + { + list.Add(disposable); + } + } + var result = new ReadonlyDisposableCollection(list); + return result; + } + + public static IDisposable AddDisposableHandler( + this RoutedEvent routedEvent, + EventHandler handler, + params TControl?[] controls) + where TArgs : RoutedEventArgs + where TControl: Interactive { List list = new List(controls.Length); foreach (var t in controls) @@ -53,7 +151,8 @@ public static IDisposable AddDisposableHandler(this RoutedEvent ro return result; } - public static IDisposable AddDisposableHandler(this RoutedEvent routedEvent, + public static IDisposable AddDisposableHandler( + this RoutedEvent routedEvent, EventHandler handler, RoutingStrategies strategies = RoutingStrategies.Bubble | RoutingStrategies.Direct, bool handledEventsToo = false, @@ -72,4 +171,49 @@ public static IDisposable AddDisposableHandler(this RoutedEvent ro var result = new ReadonlyDisposableCollection(list); return result; } + + public static IDisposable AddDisposableHandler( + this RoutedEvent routedEvent, + EventHandler handler, + RoutingStrategies strategies = RoutingStrategies.Bubble | RoutingStrategies.Direct, + bool handledEventsToo = false, + params TControl?[] controls) + where TArgs : RoutedEventArgs + where TControl: Interactive + { + List list = new List(controls.Length); + foreach (var t in controls) + { + var disposable = t?.AddDisposableHandler(routedEvent, handler, strategies, handledEventsToo); + if (disposable != null) + { + list.Add(disposable); + } + } + var result = new ReadonlyDisposableCollection(list); + return result; + } + + public static IDisposable AddDisposableHandler( + this RoutedEvent routedEvent, + EventHandler handler, + IEnumerable controls, + RoutingStrategies strategies = RoutingStrategies.Bubble | RoutingStrategies.Direct, + bool handledEventsToo = false) + where TArgs : RoutedEventArgs + where TControl: Interactive + { + // list is not initialized with controls.Count() to avoid multiple enumeration + var list = new List(); + foreach (var t in controls) + { + var disposable = t?.AddDisposableHandler(routedEvent, handler, strategies, handledEventsToo); + if (disposable != null) + { + list.Add(disposable); + } + } + var result = new ReadonlyDisposableCollection(list); + return result; + } } \ No newline at end of file diff --git a/test/Irihi.Avalonia.Shared.UnitTest.Public/Helpers/AvaloniaPropertyExtensionTest.cs b/test/Irihi.Avalonia.Shared.UnitTest.Public/Helpers/AvaloniaPropertyExtensionTest.cs index 8e78b2e..3549ca4 100644 --- a/test/Irihi.Avalonia.Shared.UnitTest.Public/Helpers/AvaloniaPropertyExtensionTest.cs +++ b/test/Irihi.Avalonia.Shared.UnitTest.Public/Helpers/AvaloniaPropertyExtensionTest.cs @@ -40,7 +40,17 @@ public void Property_MultipleObject_InArray() Button b1 = new Button(); Button b2 = new Button(); Button[] buttons = {b1, b2}; - Visual.IsVisibleProperty.SetValue(true, buttons); + Visual.IsVisibleProperty.SetValue(true, buttons); + Assert.True(b1.IsVisible); + Assert.True(b2.IsVisible); + } + + [Fact] + public void Property_MultipleObject_InList() + { + Button b1 = new Button(); + Button b2 = new Button(); + Visual.IsVisibleProperty.SetValue(true, new List