Introducing Xamarin Forms Behaviors

Corrado Cavalli
Corrado Cavalli
Published in
5 min readSep 3, 2014

The goal of this post is to introduce you to the Xamarin.Forms.Behavior package available on NuGet, if you landed here I presume you already know what Xamarin Forms is, if not, follow this link so you’ll understand why so many developers are excited about it.

Now that I can assume you’re a Xamarin Forms master, let’s concentrate on Behaviors. Once I read Xamarin Forms documentation I was really happy to see that you can design cross-platforms user interfaces using XAML and that the XAML support in Xamarin Forms is nearly identical to the one available in Windows development apart some minor differences.

If you don’t know what a Behavior is I can summarize it for you in this sentence: The capabity to add code inside a UI described using XAML” the question now is: Why should I add code inside XAML, hasn’t code behind created just for this? well, yes and no, if you know MVVM (if not, you should!) you’ll know that the entire logic should reside inside the VieModel associated with the View and that communication between View and ViewModel should happen (in a perfect world) through Databinding.

Unfortunately in “real” world this is not always possible and you have to use code to make things work, often this code resides in code behind and for this reason is not testable and not even reusable.

Let’s take an example: A simple view made up of two Entry elements and a Button, the View has a ViewModel associated to its BindingContext and we want the button to be enabled only when both Entry fields are not empty and it’s enabled state must toggle “live” while user typing.

This is the XAML contained inside Xamarin Forms’s PCL project:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Xamarin.Behaviors.Demo.Views.MainView">
<StackLayout>
<Entry Placeholder="Enter Firstname" />
<Entry Placeholder="Enter Lastname" />
<Button Text="Ok" Command="{Binding TestCommand}" />
</StackLayout>
</ContentPage>

and here’s the ViewModel:

public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string firstName = "Nome";
private string lastName = "Cognome";
private Command testCommand;
private Command<object> unfocusedCommand;
private string message;
private string welcomeMessage;

public string FirstName
{
get { return this.firstName; }
set
{
if (value != this.firstName)
{
this.firstName = value;
this.RaisePropertyChanged();
this.TestCommand.ChangeCanExecute();
}
}
}

public string LastName
{
get { return this.lastName; }
set
{
if (value != this.lastName)
{
this.lastName = value;
this.RaisePropertyChanged();
this.TestCommand.ChangeCanExecute();
}
}
}

public string Message
{
get {return this.message; }
private set
{
if (value != this.message)
{
this.message = value;
this.RaisePropertyChanged();
}
}
}
public string WelcomeMessage
{
get { return this.welcomeMessage;}
set
{
if (value != this.welcomeMessage)
{
this.welcomeMessage = value;
this.RaisePropertyChanged();
}
}
}

public Command TestCommand
{
get
{
return this.testCommand ?? (this.testCommand = new Command(
() =>
{
this.WelcomeMessage = string.Format("Hello {0} {1}", this.FirstName, this.LastName);
},
() =>
{
return !string.IsNullOrEmpty(this.FirstName) && !string.IsNullOrEmpty(this.LastName);
}));
}
}
public Command<object> UnfocusedCommand
{
get
{
return this.unfocusedCommand ?? (this.unfocusedCommand = new Command<object>(
(param) =>
{
this.Message = string.Format("Unfocused raised with param {0}", param);
},
(param) =>
{
// CanExecute delegate
return true;
}));
}
}

protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}

ViewModel is associated with the View’s constructor for brevity:

public partial class MainView
{
public MainView()
{
InitializeComponent();
this.BindingContext = new MainViewModel();
}
}

As you see the Button is connected to ViewModel’s TestCommand via Databinding and thanks to ICommand interface it is enabled only when both ViewModel’s FirstName and LastName properties are not empty.

Now the hardest part: How do we update those properties when Entry content changes?

Easy: we subscribe Entry’s TextChanged method and when it fires we update associated property. Cool, but wouldn’t it be nice if we could encapsulate this logic into a reusable component, usable in XAML, so that we don’t need to reinvent the wheel each time?

Here’s where Behaviors can help you.

Install Xamarin.Forms.Behaviors Package from NuGet and and create a class that inherits from Behavior<T> where <T> is the UI component that the behavior will attach to, in our case the Entry element.

public class TextChangedBehavior : Behavior<Entry>
{
public static readonly BindableProperty TextProperty = BindableProperty.Create<TextChangedBehavior, string>(p => p.Text, null, propertyChanged: OnTextChanged);
private static void OnTextChanged(BindableObject bindable, string oldvalue, string newvalue)
{
(bindable as TextChangedBehavior).AssociatedObject.Text = newvalue;
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
protected override void OnAttach()
{
this.AssociatedObject.TextChanged += this.OnTextChanged;
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
this.Text = e.NewTextValue;
}
protected override void OnDetach()
{
this.AssociatedObject.TextChanged -= this.OnTextChanged;
}
}

Behavior and Behavior<T> both have OnAttach and OnDetach methods that gets invoked when the behavior is attached/detached from parent UI element, so we subscribe TextChanged event and when it triggers we update behavior’s bindable property Text.

I’ll be you’re now wondering: How do I use it in my XAML? very easy, here’s the updated XAML for Entry element (just first one indicated for brevity)

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:b="clr-namespace:Xamarin.Behaviors;assembly=Xamarin.Behaviors"
x:Class="Xamarin.Behaviors.Demo.Views.MainView">
<StackLayout>
<Entry Placeholder="Enter Firstname" >
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<b:TextChangedBehavior Text="{Binding FirstName, Mode=TwoWay}" />
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</Entry>
...
</StackLayout>
</ContentPage

After adding a xmlns pointing to Xamarin.Forms.Behavior namespace we “inject” the code into XAML, so now as we type on Entry the Firstname property it’s updated (and vice versa of course thanks to INotifyPropertyChanged and Two Way binding mode.)

One of the real advantages of using Behaviors in Windows Development is that they’re visually supported by Expression Blend design tool, so you don’t even need to write any XAML, just drag the behavior and configure it using point and click

Smile

unfortunately since we don’t even have a XAML designer in Xamarin Forms typing is the only available solution at the moment.

If you think the syntax is quite boring I agree, that’s why inside the project on GitHub I added a XML snippet that generates the surrounding code for you, just grab it and import it in Visual Studio, add the behavior syntax and press Ctrl+K+S

image

and you’ll have the plumbing code added for you, don’t forget to add required xmlns directive/s.

xmlns:b="clr-namespace:Xamarin.Behaviors;assembly=Xamarin.Behaviors"

since it’s not added automatically by the snippet.

Am not a Xamarin Studio expert so I don’t know if it support XML Expansions, if so send me the snippet and I’ll add it to the project.

Here’s the XAML taken from the example available on GitHub:

<Entry Placeholder="Enter Firstname" >
<b:Interaction.Behaviors>
<b:BehaviorCollection>
<b:TextChangedBehavior Text="{Binding FirstName, Mode=TwoWay}" />
<b:EventToCommand EventName="Unfocused" Command="{Binding UnfocusedCommand}" CommandParameter="FirstName" />
</b:BehaviorCollection>
</b:Interaction.Behaviors>
</Entry>

the example shows two behaviors included in the package, TextChangedBehavior and EventToCommand, a behavior that invokes a Command when an event occurs.

Congratulations! you’re now able to write your own behavior, group them in a portable library and reuse it in every Xamarin Forms project.

If you’re already a XAML developer you already know what behaviors are and I hope you’ll like to have them in Xamarin Forms, if not I encourage you to play with it, personally can’t even think using XAML with MVVM without them.

Ok, now let’s dream about a Xamarin Forms designer supporting the same Behavior infrastructure as Expression Blend, am I asking too much? we’ll see.

Cheers!

NuGet Package: here

GitHub repo: here

--

--

Corrado Cavalli
Corrado Cavalli

Senior Sofware Engineer at Microsoft, former Xamarin/Microsoft MVP mad about technology. MTB & Ski mountaineering addicted.