Behaviors
Behaviors allow functionality to be added to UI controls without having to subclass them. Instead, the functionality is implemented in a behavior class and attached to the control as if it was part of the control itself. Behaviors enable you to implement code that you would normally have to write as code-behind, because it directly interacts with the API of the control, in such a way that it can be concisely attached to the control, and packaged for reuse across more than one view or app. In the context of MVVM, behaviors are a useful approach for connecting controls to commands.
The EventToCommandBehavior
class provide a convenient way to, in XAML, "bind" events to ICommand
according to MVVM paradigm to avoid code behind.
Using the EventToCommandBehavior
The EventToCommandBehavior
expose the following properties
- EventName The name of the event to listen to. For example ItemTapped
- Command The
ICommand
that will be executed when the event is raised - CommandParameter The parameter that will be sent to the
ICommand.Execute(object)
method - Converter Instance of
IValueConverter
that allows operating on theEventArgs
type for the EventName - IsSelected Return true if element selected otherwise false
- RemoveSelection If this attribute is true will put SelectedItem to null on ListView
First declare the namespace and assembly in where EventToCommandBehavior
is declared and declare a XML-namespace.
xmlns:behavior="clr-namespace:AssecoSEE.DEM.Components.Behaviors;assembly=AssecoSEE.DEM.Components"
Invoking Behaviors from a View
The EventToCommandBehavior is particularly useful for attaching a command to a control that doesn't support commands. For example, the TransactionListView uses the EventToCommandBehavior to execute the TappedOnListItemCommand when the ItemTapped event fires on the ListView that lists the user's transactions, as shown in the following code:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyNamespace.ContentPage"
xmlns:behavior="clr-namespace:AssecoSEE.DEM.Components.Behaviors;assembly=AssecoSEE.DEM.Components">
<ListView x:Name="TransactionListView">
<ListView.Behaviors>
<behavior:EventToCommandBehavior Source="{x:Reference TransactionListView}" EventName="ItemTapped" Command="{Binding TappedOnListItemCommand}" RemoveSelection="true" />
</ListView.Behaviors>
</ListView>
</ContentPage>
Account Formatter and IBAN Validator###
<ctrl:EntryNumber x:Name="CreditorAccountNumberEntry"
Placeholder="{ext:Translate payment_creditor_account}"
DisplayText="{Binding PaymentData.CreditorAccount.AccountNumber, Mode=TwoWay}"
ErrorText="{Binding ValidationData[CreditorAccountAccountNumber].StringValue}">
<ctrl:EntryNumber.Behaviors>
<behaviors:AccountNumberFormatterBehavior x:Name="accountNumberFormatterBehavior" />
</ctrl:EntryNumber.Behaviors>
</ctrl:EntryNumber>
public class AccountNumberFormatterBehavior : Behavior<EntryNumber>
{
protected IAccountNumberFormatter formatter;
///
/// Attaches when the page is first created.
///
protected override void OnAttachedTo(EntryNumber entry)
{
formatter = DEMApplication.Current.ResolveService<IAccountNumberFormatter>();
if (formatter != null)
{
entry.Unfocused += OnUnfocused;
}
base.OnAttachedTo(entry);
}
private void OnUnfocused(object sender, FocusEventArgs args)
{
if (formatter!=null && sender is EntryNumber ctrl && !String.IsNullOrWhiteSpace(ctrl.DisplayText))
{
var output = formatter.Format(ctrl.DisplayText.Trim());
if (output != null)
{
ctrl.DisplayText = output;
}
}
}
}
Other resources