Overview
The EventToCommandBehavior
class is a reusable Xamarin.Forms custom
behavior that executes a command in response to any event firing. By
default, the event arguments for the event will be passed to the
command, and can be optionally converted by an
IValueConverter
implementation.
The following behavior properties must be set to use the behavior:
- EventName – the name of the event the behavior listens to.
- Command – the
ICommand
to be executed. The behavior expects to find the ICommand
instance on the
BindingContext
of the attached control, which may be inherited from a parent element.
The following optional behavior properties can also be set:
- CommandParameter – an
object
that will be passed to the command.
- Converter – an
IValueConverter
implementation that will change the format of the event argument data
as it's passed between source and target by the binding engine.
Note: The EventToCommandBehavior
is a custom class that can be located in the EventToCommand Behavior
sample,
and is not part of Xamarin.Forms.
Creating the Behavior
The EventToCommandBehavior
class derives from the BehaviorBase<T>
class, which in turn derives from the
Behavior
class. The purpose of the BehaviorBase<T>
class is to provide a base
class for any Xamarin.Forms behaviors that require the
BindingContext
of the behavior to be set to the attached control. This ensures that
the behavior can bind to and execute the ICommand
specified by the
Command
property when the behavior is consumed.
The BehaviorBase<T>
class provides an overridable
OnAttachedTo
method that sets the
BindingContext
of the behavior and an overridable
OnDetachingFrom
method that cleans up the BindingContext
. In addition, the class
stores a reference to the attached control in the AssociatedObject
property.
Implementing Bindable Properties
The EventToCommandBehavior
class defines four
BindableProperty
instances that execute a user defined command when an event fires.
These properties are shown in the following code example:
C#:
public class EventToCommandBehavior : BehaviorBase<View> {
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 { ... }
public ICommand Command { ... }
public object CommandParameter { ... }
public IValueConverter Converter { ... }
...
}
When the EventToCommandBehavior
class is consumed, the Command
property should be data bound to an ICommand
to be executed in
response to the event firing that's defined in the EventName
property. The behavior will expect to find the ICommand
on the
BindingContext
of the attached control.
By default, the event arguments for the event will be passed to the
command. This data can be optionally converted as it's passed between
source and target by the binding engine, by specifying an IValueConverter
implementation as the Converter
property value. Alternatively, a
parameter can be passed to the command by specifying the
CommandParameter
property value.
Implementing the Overrides
The EventToCommandBehavior
class overrides the
OnAttachedTo
and
OnDetachingFrom
methods of the BehaviorBase<T>
class, as shown in the following code
example:
C#:
public class EventToCommandBehavior : BehaviorBase<View> {
...
protected override void OnAttachedTo (View bindable) {
base.OnAttachedTo (bindable);
RegisterEvent (EventName);
}
protected override void OnDetachingFrom (View bindable) {
DeregisterEvent (EventName);
base.OnDetachingFrom (bindable);
}
...
}
The
OnAttachedTo
method performs setup by calling the RegisterEvent
method, passing
in the value of the EventName
property as a parameter. The
OnDetachingFrom
method performs cleanup by calling the DeregisterEvent
method,
passing in the value of the EventName
property as a parameter.
Implementing the Behavior Functionality
The purpose of the behavior is to execute the command defined by the
Command
property in response to the event firing that's defined by
the EventName
property. }The core behavior functionality is shown in
the following code example:
C#:
public class EventToCommandBehavior : BehaviorBase<View> {
...
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 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);
}
}
...
}
The RegisterEvent
method is executed in response to the
EventToCommandBehavior
being attached to a control, and it receives
the value of the EventName
property as a parameter. The method then
attempts to locate the event defined in the EventName
property, on
the attached control. Provided that the event can be located, the
OnEvent
method is registered to be the handler method for the event.
The OnEvent
method is executed in response to the event firing
that's defined in the EventName
property. Provided that the
Command
property references a valid ICommand
, the method attempts
to retrieve a parameter to pass to the ICommand
as follows:
- If the
CommandParameter
property defines a parameter, it is retrieved.
- Otherwise, if the
Converter
property defines an IValueConverter
implementation, the converter is executed and converts the event
argument data as it's passed between source and target by the
binding engine.
- Otherwise, the event arguments are assumed to be the parameter.
The data bound ICommand
is then executed, passing in the parameter
to the command, provided that the
CanExecute
method returns true
.
Although not shown here, the EventToCommandBehavior
also includes a
DeregisterEvent
method that's executed by the
OnDetachingFrom
method. The DeregisterEvent
method is used to locate and deregister
the event defined in the EventName
property, to cleanup any
potential memory leaks.
Consuming the Behavior
The EventToCommandBehavior
class can be attached to the
Behaviors
collection of a control, as demonstrated in the following XAML code
example:
XAML:
<ListView ItemsSource="{Binding People}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Behaviors>
<local:EventToCommandBehavior EventName="ItemSelected" Command="Binding OutputAgeCommand}" Converter="{StaticResource SelectedItemConverter}" />
</ListView.Behaviors>
</ListView>
<Label Text="{Binding SelectedItemText}" />
The equivalent C# code is shown in the following code example:
C#:
var listView = new ListView();
listView.SetBinding(ItemsView<Cell>.ItemsSourceProperty, "People");
listView.ItemTemplate = new DataTemplate(() =>
{
var textCell = new TextCell();
textCell.SetBinding(TextCell.TextProperty, "Name");
return textCell;
});
listView.Behaviors.Add(new EventToCommandBehavior {
EventName = "ItemSelected",
Command = ((HomePageViewModel)BindingContext).OutputAgeCommand,
Converter = new SelectedItemEventArgsToSelectedItemConverter()
});
var selectedItemLabel = new Label();
selectedItemLabel.SetBinding(Label.TextProperty, "SelectedItemText");
The Command
property of the behavior is data bound to the
OutputAgeCommand
property of the associated ViewModel, while the
Converter
property is set to the SelectedItemConverter
instance,
which returns the
SelectedItem
of the
ListView
from the
SelectedItemChangedEventArgs
.
At runtime, the behavior will respond to interaction with the control.
When an item is selected in the
ListView
,
the
ItemSelected
event will fire, which will execute the OutputAgeCommand
in the
ViewModel. In turn this updates the ViewModel SelectedItemText
property that the
Label
binds to, as shown in the following screenshots:

The advantage of using this behavior to execute a command when an
event fires, is that commands can be associated with controls that
weren't designed to interact with commands. In addition, this removes
boilerplate event handling code from code-behind files.