Added an EventListenerBehaviour for listening for events raised from the source
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user