Many years ago I wrote a behaviours library for Xamarin.Forms. The conventional view was that behaviours extend the functionality of controls, with typical examples validating user text input. Inspired by the then Blend SDK, my thought was that behaviors can be split into two concepts. Behaviours are attached to a control and listen for something to happen. When the something happens, it triggers one or more actions in response. So actions are invoked by behaviours and executed on a specified control. Typical behaviors are listening for an event firing, or data changing. Typical actions are invoking a command, invoking a method, setting a property etc.
I ended up producing a behaviours library for Xamarin.Forms, based on the Blend SDK, that I shipped on NuGet and for a while it was moderately successful. I updated it from time to time, but eventually forgot all about it.
I’ve now resurrected it for .NET MAUI. But I’m not going to ship it as a NuGet. Doing so for the previous version caused me lots of work that I’d like to avoid now.
What is it?
Behaviours for .NET MAUI is a class library I’ve created that can be consumed by .NET MAUI apps. It supports the following scenarios:
- Invoking commands from XAML when an event fires or when data changes.
- Invoking methods from XAML (in the view or view model) when an event fires or when data changes.
- Setting properties from XAML (in the view or view model) when an event fires or when data changes.
- Invoke animations from XAML, including compound animations, when an event fires or when data changes.
- Triggering a specified
VisualState
on aVisualElement
from XAML, when an event fires or when data changes.
The result of using the library is that you can eliminate lots of boiler plate C# code, instead moving it to XAML.
Behaviours
The library contains the following behaviours:
EventHandlerBehavior
- listens for a specific event to occur, and executes one or more actions in response.DataChangedBehavior
- listens for the bound data to meet a specified condition, and executes one or more actions in response.
Actions
The library contains the following actions:
InvokeCommandAction
- executes a specifiedICommand
when invoked.InvokeMethodAction
- executes a method on a specified object when invoked.SetPropertyAction
- changes a specified property to a specified value.FadeAction
- performs a fade animation when invoked,RotateAction
- performs a rotate animation when invoked.ScaleAction
- performs a scale animation when invoked.TranslateAction
- performs a translate animation when invoked.GoToStateAction
- invokes visual state changes.
Where is it?
You can download the library and a sample that demos it from its repo.
How do I use it?
Using the library is a three step process:
- Clone the library from its repo and add the BehaviorsLibrary class library project to your .NET MAUI solution.
- Add a reference to the BehaviorsLibrary project to your app project.
- Add an
xmlns
to the library to your XAML file, and then consume the required behaviors/actions from XAML.
The following code example shows an example of using the EventHandlerBehavior
to invoke two commands:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:behaviors="clr-namespace:Behaviors;assembly=Behaviors"
...>
<ContentPage.Resources>
<converters:SelectedItemEventArgsToSelectedItemConverter x:Key="SelectedItemConverter" />
</ContentPage.Resources>
...
<ListView x:Name="listView"
ItemsSource="{Binding People}">
<ListView.Behaviors>
<behaviors:EventHandlerBehavior EventName="ItemSelected">
<behaviors:InvokeCommandAction Command="{Binding ItemSelectedCommand}"
Converter="{StaticResource SelectedItemConverter}" />
<behaviors:InvokeCommandAction Command="{Binding OutputAgeCommand}"
Converter="{StaticResource SelectedItemConverter}"
ConverterParameter="35" />
</behaviors:EventHandlerBehavior>
</ListView.Behaviors>
</ListView>
</ContentPage>
In this example, when the ListView.ItemSelected
event is raised, the ItemSelectedCommand
and OutputAgeCommand
are sequentially executed on the bound view model (the InvokeCommandAction
class expects to find the Command
objects on the BindingContext
of the attached object). The advantage of this approach is that it enables commands to be associated with controls that weren’t designed to interact with commands, thereby removing boiler-plate event handling code from code-behind files.
In the coming weeks I’ll explore all the functionality the library offers in more detail.
No comments:
Post a Comment