Added an EventListenerBehaviour for listening for events raised from the source

This commit is contained in:
TheXamlGuy
2024-09-29 15:01:02 +01:00
parent 4b732791bd
commit 379d43d553
3 changed files with 135 additions and 10 deletions
@@ -4,7 +4,8 @@ using Avalonia.Xaml.Interactivity;
namespace Toolkit.UI.Avalonia; namespace Toolkit.UI.Avalonia;
public class AttachedEventTriggerBehaviour : Trigger public class AttachedEventTriggerBehaviour :
Trigger
{ {
public static readonly StyledProperty<RoutedEvent> RoutedEventProperty = public static readonly StyledProperty<RoutedEvent> RoutedEventProperty =
AvaloniaProperty.Register<AttachedEventTriggerBehaviour, RoutedEvent>(nameof(RoutedEvent)); AvaloniaProperty.Register<AttachedEventTriggerBehaviour, RoutedEvent>(nameof(RoutedEvent));
@@ -0,0 +1,133 @@
using Avalonia;
using Avalonia.Xaml.Interactivity;
using System.Reactive;
using System.Reflection;
namespace Toolkit.UI.Avalonia;
public class EventListenerBehaviour :
Trigger
{
public static readonly StyledProperty<string> EventNameProperty =
AvaloniaProperty.Register<EventListenerBehaviour, string>(nameof(EventName));
public static readonly StyledProperty<object> SourceProperty =
AvaloniaProperty.Register<EventListenerBehaviour, object>(nameof(Source));
private Delegate? eventHandler;
private object? resolvedSource;
static EventListenerBehaviour()
{
EventNameProperty.Changed.Subscribe(new AnonymousObserver<AvaloniaPropertyChangedEventArgs<string>>(EventNamePropertyChanged));
SourceProperty.Changed.Subscribe(new AnonymousObserver<AvaloniaPropertyChangedEventArgs<object>>(SourcePropertyChanged));
}
public string EventName
{
get => GetValue(EventNameProperty);
set => SetValue(EventNameProperty, value);
}
public object Source
{
get => GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
private static void EventNamePropertyChanged(AvaloniaPropertyChangedEventArgs<string> args)
{
if (args.Sender is EventListenerBehaviour behaviour)
{
if (args.OldValue.GetValueOrDefault() is string oldValue)
{
behaviour.UnregisterEvent(oldValue);
}
if (args.NewValue.GetValueOrDefault() is string newValue)
{
behaviour.RegisterEvent(newValue);
}
}
}
private static void SourcePropertyChanged(AvaloniaPropertyChangedEventArgs<object> args)
{
if (args.Sender is EventListenerBehaviour behaviour)
{
behaviour.SetResolvedSource(args.GetNewValue<object>());
}
}
private void OnEventRaised(object? sender, EventArgs args)
{
if (IsEnabled)
{
Interaction.ExecuteActions(AssociatedObject, Actions, null);
}
}
private void RegisterEvent(string eventName)
{
if (eventName is { Length: 0 })
{
return;
}
if (resolvedSource is null)
{
return;
}
Type sourceType = resolvedSource.GetType();
if (sourceType.GetEvent(EventName) is EventInfo eventInfo)
{
eventInfo.AddEventHandler(resolvedSource, new EventHandler(OnEventRaised));
}
}
private void SetResolvedSource(object? newSource)
{
if (resolvedSource == newSource)
{
return;
}
if (resolvedSource is not null)
{
UnregisterEvent(EventName);
}
resolvedSource = newSource;
if (resolvedSource is not null)
{
RegisterEvent(EventName);
}
}
private void UnregisterEvent(string eventName)
{
if (eventHandler is null)
{
return;
}
if (eventName is { Length: 0 })
{
return;
}
if (resolvedSource is null)
{
return;
}
Type sourceType = resolvedSource.GetType();
if (sourceType.GetEvent(EventName) is EventInfo eventInfo)
{
eventInfo.RemoveEventHandler(resolvedSource, new EventHandler(OnEventRaised));
}
}
}
@@ -12,21 +12,12 @@ public class KeyBindingTriggerBehaviour :
public static readonly StyledProperty<KeyGesture> GestureProperty = public static readonly StyledProperty<KeyGesture> GestureProperty =
AvaloniaProperty.Register<KeyBindingTriggerBehaviour, KeyGesture>(nameof(Gesture)); AvaloniaProperty.Register<KeyBindingTriggerBehaviour, KeyGesture>(nameof(Gesture));
public static readonly StyledProperty<bool> IsEnabledProperty =
AvaloniaProperty.Register<KeyBindingTriggerBehaviour, bool>(nameof(IsEnabled), true);
public KeyGesture Gesture public KeyGesture Gesture
{ {
get => GetValue(GestureProperty); get => GetValue(GestureProperty);
set => SetValue(GestureProperty, value); set => SetValue(GestureProperty, value);
} }
public bool IsEnabled
{
get => GetValue(IsEnabledProperty);
set => SetValue(IsEnabledProperty, value);
}
public event EventHandler? CanExecuteChanged; public event EventHandler? CanExecuteChanged;
protected override void OnAttached() protected override void OnAttached()