133 lines
4.4 KiB
C#
133 lines
4.4 KiB
C#
using System;
|
|
using System.Reflection;
|
|
using System.Windows.Input;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Aurora.Design.Behaviors
|
|
{
|
|
public class EventToCommandBehavior : BehaviorBase<View>
|
|
{
|
|
Delegate eventHandler;
|
|
|
|
public static readonly BindableProperty EventNameProperty = BindableProperty.Create("EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
|
|
public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(EventToCommandBehavior), null);
|
|
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(EventToCommandBehavior), null);
|
|
public static readonly BindableProperty InputConverterProperty = BindableProperty.Create("Converter", typeof(IValueConverter), typeof(EventToCommandBehavior), null);
|
|
|
|
public string EventName
|
|
{
|
|
get { return (string)GetValue(EventNameProperty); }
|
|
set { SetValue(EventNameProperty, value); }
|
|
}
|
|
|
|
public ICommand Command
|
|
{
|
|
get { return (ICommand)GetValue(CommandProperty); }
|
|
set { SetValue(CommandProperty, value); }
|
|
}
|
|
|
|
public object CommandParameter
|
|
{
|
|
get { return GetValue(CommandParameterProperty); }
|
|
set { SetValue(CommandParameterProperty, value); }
|
|
}
|
|
|
|
public IValueConverter Converter
|
|
{
|
|
get { return (IValueConverter)GetValue(InputConverterProperty); }
|
|
set { SetValue(InputConverterProperty, value); }
|
|
}
|
|
|
|
protected override void OnAttachedTo(View bindable)
|
|
{
|
|
base.OnAttachedTo(bindable);
|
|
RegisterEvent(EventName);
|
|
}
|
|
|
|
protected override void OnDetachingFrom(View bindable)
|
|
{
|
|
DeregisterEvent(EventName);
|
|
base.OnDetachingFrom(bindable);
|
|
}
|
|
|
|
void RegisterEvent(string name)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
|
|
if (eventInfo == null)
|
|
{
|
|
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't register the '{0}' event.", EventName));
|
|
}
|
|
MethodInfo methodInfo = typeof(EventToCommandBehavior).GetTypeInfo().GetDeclaredMethod("OnEvent");
|
|
eventHandler = methodInfo.CreateDelegate(eventInfo.EventHandlerType, this);
|
|
eventInfo.AddEventHandler(AssociatedObject, eventHandler);
|
|
}
|
|
|
|
void DeregisterEvent(string name)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(name))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (eventHandler == null)
|
|
{
|
|
return;
|
|
}
|
|
EventInfo eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
|
|
if (eventInfo == null)
|
|
{
|
|
throw new ArgumentException(string.Format("EventToCommandBehavior: Can't de-register the '{0}' event.", EventName));
|
|
}
|
|
eventInfo.RemoveEventHandler(AssociatedObject, eventHandler);
|
|
eventHandler = null;
|
|
}
|
|
|
|
void OnEvent(object sender, object eventArgs)
|
|
{
|
|
if (Command == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
object resolvedParameter;
|
|
if (CommandParameter != null)
|
|
{
|
|
resolvedParameter = CommandParameter;
|
|
}
|
|
else if (Converter != null)
|
|
{
|
|
resolvedParameter = Converter.Convert(eventArgs, typeof(object), null, null);
|
|
}
|
|
else
|
|
{
|
|
resolvedParameter = eventArgs;
|
|
}
|
|
|
|
if (Command.CanExecute(resolvedParameter))
|
|
{
|
|
Command.Execute(resolvedParameter);
|
|
}
|
|
}
|
|
|
|
static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
|
|
{
|
|
var behavior = (EventToCommandBehavior)bindable;
|
|
if (behavior.AssociatedObject == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string oldEventName = (string)oldValue;
|
|
string newEventName = (string)newValue;
|
|
|
|
behavior.DeregisterEvent(oldEventName);
|
|
behavior.RegisterEvent(newEventName);
|
|
}
|
|
}
|
|
}
|