Monday, 21 March 2016

Xamarin.Forms Behaviors: DataChangedBehavior and InvokeCommandAction

Previously, I demonstrated using the EventHandlerBehavior and SetPropertyAction classes to set one or more properties when an event fires. The Behaviors Library for Xamarin.Forms has the notion of behaviors and actions. A behavior is attached to a control and listens for something to happen, such as an event firing. When the “something” happens, it triggers one or more actions, such as invoking a method or command. Actions are invoked by behaviors and executed on a selected control.

In this blog post, I’ll demonstrate using the DataChangedBehavior and InvokeCommandAction classes to invoke one or more commands when data changes.

Invoking a Command when Data Changes

The DataChangedBehavior class listens for the bound data to meet a specified condition, and executes one or more actions in response. It requires you to set the following properties:

  • Binding – an object that represents the bound object that the behavior will listen to.
  • ComparisonCondition – a ComparisonCondition enumeration value that represents the comparison to be performed between the values of the Binding and Value properties. The enumeration values are: Equal, NotEqual, LessThan, LessThanOrEqual, GreaterThan, GreaterThanOrEqual.
  • Value – an object that represents the value to be compared with the value of the Binding property.
  • Actions – one or more actions that should be executed in response to the bound data changing. Note that this property is set indirectly.

The InvokeCommandAction class executes a specified ICommand when invoked. It requires you to set a Command property to an ICommand instance, and CommandParameter and Converter properties can be optionally set. The CommandParameter property should be set to an object instance, with the Converter property being set to an instance of a class that implements IValueConverter. The ICommand specified in the Command property will then be executed, with the CommandParameter and Converter values being used if specified.

The following code shows an example of using the DataChangedBehavior to invoke a command:

<ContentPage.BindingContext> <local:InvokeCommandDemoPageViewModel /> </ContentPage.BindingContext> ... <Entry x:Name="entry" Placeholder="Enter Xamarin here"> <Entry.Behaviors> <behaviors:DataChangedBehavior Binding="{Binding Path=Text, Source={x:Reference entry}}" ComparisonCondition="Equal" Value="Xamarin"> <behaviors:InvokeCommandAction Command="{Binding OutputMessageCommand}" CommandParameter="{Binding Path=Text, Source={x:Reference entry}}" /> </behaviors:DataChangedBehavior> </Entry.Behaviors> </Entry> <Label Text="{Binding MessageText}" />

When the value of the Entry.Text property becomes equal to “Xamarin”, the OutputMessageCommand is executed. The InvokeCommandAction class expects to find the ICommand instance on the BindingContext of the attached object, and in this case the BindingContext has been set by a parent element to an instance of the InvokeCommandDemoPageViewModel class. The CommandParameter passes the value of the Entry.Text property to the Execute delegate of the Command. Note that the Actions property of the DataChangedBehavior is set indirectly by creating the InvokeCommandAction instance as a child of the DataChangedBehavior instance.

The advantage of using the DataChangedBehavior and InvokeCommandAction classes is that commands can be executed in response to data changing, removing boiler-plate code from code-behind files.

The sample application that this code comes from can be downloaded from GitHub.

Summary

The DataChangedBehavior class listens for the bound data to meet a specified condition, and executes one or more actions in response. The InvokeCommandAction class executes a specified ICommand when invoked. By using these two classes, commands can be executed in response to data changing, removing boiler-plate code from code-behind files.

Monday, 14 March 2016

Xamarin.Forms Behaviors: EventHandlerBehavior and SetPropertyAction

Previously, I demonstrated using the EventHandlerBehavior and InvokeMethodAction classes to invoke one or more methods when an event fires. The Behaviors Library for Xamarin.Forms has the notion of behaviors and actions. A behavior is attached to a control and listens for something to happen, such as an event firing. When the “something” happens, it triggers one or more actions, such as invoking a method or command. Actions are invoked by behaviors and executed on a selected control.

In this blog post, I’ll demonstrate using the EventHandlerBehavior and SetPropertyAction classes to set one or more properties when an event fires.

Setting a Property when an Event Fires

The EventHandlerBehavior class listens for a specified event to occur, and executes one or more actions in response. It requires you to set an EventName property to the event that you want the behavior to listen to, and an Actions property to one or more actions that should be executed in response to the event firing.

The SetPropertyAction class sets a specified property when invoked. It requires you to set a TargetObject property to an object that exposes the property of interest, a PropertyName property to the name of the property to be set, and a Value property to an object that represents the property value to be set.

The following code example shows an example of using the EventHandlerBehavior and SetPropertyAction classes to set three properties:

<ContentPage.BindingContext> <local:SetPropertyDemoPageViewModel /> </ContentPage.BindingContext> <Button x:Name="button" Text="Change Page and ViewModel Properties"> <Button.Behaviors> <behaviors:EventHandlerBehavior EventName="Clicked"> <behaviors:SetPropertyAction TargetObject="{x:Reference boxView}" PropertyName="Color" Value="{StaticResource ColorRed}" /> <behaviors:SetPropertyAction TargetObject="{Binding}" PropertyName="MessageText" Value="Message text changed" /> <behaviors:SetPropertyAction TargetObject="{x:Reference button}" PropertyName="IsEnabled" Value="false" /> </behaviors:EventHandlerBehavior> </Button.Behaviors> </Button>

When the Button.Clicked event fires, three properties are set:

  • The Color property of the BoxView instance is set to red.
  • The MessageText property of the SetPropertyDemoPageViewModel instance is set to “Message text changed”. In this case, the TargetObject property specifies that the BindingContext exposes the property of interest. Therefore, the SetPropertyAction class will search the BindingContext of the attached control for the property, which in this case is inherited from the page.
  • The IsEnabled property of the Button instance is set to false.

Note that the Actions property of the EventHandlerBehavior instance is set indirectly by creating the SetPropertyAction instances as children of the EventHandlerBehavior instance.

The advantage of combining the EventHandlerBehavior and SetPropertyAction classes is that properties of controls can easily be set without having to bind them to ViewModel properties, therefore removing boiler-plate properties from ViewModels, and boiler-plate property setting code from code-behind files.

The sample application that this code comes from can be downloaded from GitHub.

Summary

The EventHandlerBehavior class listens for a specified event to occur, and executes one or more actions in response. The SetPropertyAction class sets a specified property when invoked. The advantage of combining the EventHandlerBehavior and SetPropertyAction classes is that properties of controls can easily be set without having to bind them to ViewModel properties, therefore removing boiler-plate properties from ViewModels, and boiler-plate property setting code from code-behind files.

Monday, 7 March 2016

Xamarin.Forms Behaviors: EventHandlerBehavior and InvokeMethodAction

Previously, I demonstrated using the EventHandlerBehavior and InvokeCommandAction classes to invoke one or more commands when an event fires. The Behaviors Library for Xamarin.Forms has the notion of behaviors and actions. A behavior is attached to a control and listens for something to happen, such as an event firing. When the “something” happens, it triggers one or more actions, such as invoking a method or command. Actions are invoked by behaviors and executed on a selected control.

In this blog post, I’ll demonstrate using the EventHandlerBehavior and InvokeMethodAction classes to invoke one or more methods when an event fires.

Invoking a Method when an Event Fires

The EventHandlerBehavior class listens for a specified event to occur, and executes one or more actions in response. It requires you to set an EventName property to the event that you want the behavior to listen to, and an Actions property to one or more actions that should be executed in response to the event firing.

The InvokeMethodAction class executes a specified method when invoked. It requires you to set a TargetObject property to an object that exposes the method of interest, and a MethodName property to the name of the method to be invoked. The InvokeMethodAction class allows you to call a method with zero parameters, or a method with two parameters.

Calling a Method without Parameters

The following code shows an example of using the EventHandlerBehavior and InvokeMethodAction classes to invoke a method with no parameters:

<StackLayout.BindingContext> <local:InvokeMethodDemoPageViewModel /> </StackLayout.BindingContext> ... <Button Text="Invoke ViewModel Method"> <Button.Behaviors> <behaviors:EventHandlerBehavior EventName="Clicked"> <behaviors:InvokeMethodAction TargetObject="{Binding}" MethodName="IncrementCounter" /> </behaviors:EventHandlerBehavior> </Button.Behaviors> </Button>

When the Button.Clicked event fires, the IncrementCounter method is executed. The TargetObject property value specifies that the BindingContext exposes the method of interest. Therefore, the InvokeMethodAction class will search the BindingContext of the attached control for the method, which in this case is the InvokeMethodDemoPageViewModel instance. Note that the Actions property of the EventHandlerBehavior is set indirectly by creating the InvokeMethodAction instance as a child of the EventHandlerBehavior instance.

Calling Methods with Two Parameters

The InvokeMethodAction class also supports calling methods with parameters. However, methods with parameters must conform to a signature with two parameters such as (object sender, object params).

The following code shows an example of using the EventHandlerBehavior and InvokeMethodAction classes to invoke a method with parameters:

<StackLayout BindingContext="{x:Reference page}"> ... <Button Text="Invoke Page Method"> <Button.Behaviors> <behaviors:EventHandlerBehavior EventName="Clicked"> <behaviors:InvokeMethodAction TargetObject="{Binding}" MethodName="OnButtonClicked" /> </behaviors:EventHandlerBehavior> </Button.Behaviors> </Button> </StackLayout>

When the Button.Clicked event fires, the OnButtonClicked method is executed (which has a signature of object sender, EventArgs args). The TargetObject property value specifies that the BindingContext exposes the method of interest. Therefore, the InvokeMethodAction class will search the BindingContext of the attached control for the method, which in this case is the ContentPage. Note that the Actions property of the EventHandlerBehavior is set indirectly by creating the InvokeMethodAction instance as a child of the EventHandlerBehavior instance.

Generally, combining the EventHandlerBehavior and InvokeMethodAction classes offers no advantage over combining the EventHandlerBehavior and InvokeCommandAction classes. However, the InvokeCommandAction class can be useful when combined with other behaviors.

The sample application that this code comes from can be downloaded from GitHub.

Summary

The EventHandlerBehavior class listens for a specified event to occur, and executes one or more actions in response. The InvokeMethodAction class executes a specified method when invoked. Generally, combining the EventHandlerBehavior and InvokeCommandAction classes is preferred over combining the EventHandlerBehavior and InvokeMethodAction classes. However, the InvokeCommandAction class can be useful when combined with other behaviors.