Tuesday, 12 June 2018

Xamarin.Forms Behaviors: InvokeCommandAction and ConverterParameter

I previously mentioned that I’d published v1.4 of my Behaviors library, and that it included some new functionality. In my last blog post I looked at the SourceObject property that’s now present on the EventHandlerBehavior class. The final new item is the ConverterParameter property that now exists on the InvokeCommandAction class.

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 when the “something” the parent behavior listens for occurs, with the CommandParameter and Converter values being used if specified.

Introducing the ConverterParameter Property

In v1.4 of the Behaviors library, the InvokeCommandAction class also has an optional ConverterParameter property, of type object. When this property is set, its value is passed to the Convert and ConvertBack methods of the IValueConverter implementation, as the parameter argument.

The following XAML shows an example of the InvokeCommandAction passing a parameter to the converter:

<ListView x:Name="listView" ItemsSource="{Binding People}"> <ListView.Behaviors> <behaviors:EventHandlerBehavior EventName="ItemSelected"> <behaviors:InvokeCommandAction Command="{Binding OutputAgeCommand}" Converter="{StaticResource SelectedItemConverter}" ConverterParameter="35" /> </behaviors:EventHandlerBehavior> </ListView.Behaviors> </ListView>

When the ListView.ItemSelected event fires, the OutputAgeCommand is executed. The InvokeCommandAction class expects to find the ICommand on the BindingContext of the attached object (and the BindingContext may have been set by a parent element). The Converter property of the InvokeCommandAction instance is set to the SelectedItemConverter instance, and the value of the ConverterParameter property is passed to the SelectedItemConverter instance as the parameter argument:

public class SelectedItemEventArgsToSelectedItemConverter : IValueConverter { public object Convert (object value, Type targetType, object parameter, CultureInfo culture) { var eventArgs = value as SelectedItemChangedEventArgs; var person = eventArgs.SelectedItem as Person; if (parameter != null) { int ageParam = int.Parse(parameter.ToString()); person = new Person(person.Name, person.Age, ageParam); } return person; } ... }

The converter returns the SelectedItem of the ListView from the SelectedItemChangedEventArgs. If the parameter argument contains data, it’s converted to an int and a new Person object is constructed that contains the int value of parameter. The InvokeCommandDemoPageViewModel then uses the Person object to update the AgeText property (which the UI binds to) to a message to be output:

void OutputAge (Person person) { if (person.AgeParameter > person.Age) AgeText = string.Format("{0} is {1}. That's younger than {2}.", person.Name, person.Age, person.AgeParameter); else AgeText = string.Format("{0} is {1}. That's older than {2}.", person.Name, person.Age, person.AgeParameter); OnPropertyChanged ("AgeText"); }

While this is a contrived example, it does illustrate how the ConverterParameter property can be used to pass a parameter to the value converter, that can be used in the conversion process.

Note that even if the instance of the value converter is shared among several data bindings, the ConverterParameter property can be different to perform different conversions.

Summary

In v1.4 of the Behaviors library, the InvokeCommandAction class also has an optional ConverterParameter property, of type object. When this property is set, its value is passed to the Convert and ConvertBack methods of the IValueConverter implementation, as the parameter argument.

The sample application that this code comes from can be downloaded from GitHub, and the Behaviors library can be found on NuGet.

No comments:

Post a Comment