Understanding Multi-Binding in Xamarin Forms

 1 year ago
source link: https://xamgirl.com/understanding-multi-binding-in-xamarin-forms/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Multi-binding is a great feature that was introduced in Xamarin Forms 4.7 that allows the binding of multiple sources to a single target property. It gives us a lot of flexibility as now we don’t need to create multiple UI elements for each bindable property, which improves performance and makes our code cleaner.

Why is this important?

Before multi-binding to achieve binding multiple sources to the same property required a lot of extra effort. Since the only control that has something similar is the Label with the FormattedText property.

<Label> <Label.FormattedText> <FormattedString> <Span Text="{Binding FirstName}"/> <Span Text=" "/> <Span Text="{Binding LastName}"/> </FormattedString> </Label.FormattedText> </Label>

But what happens when we want to achieve the same with Buttons? There is no FormattedText property that we can use. MULTI-BINDING TO THE RESCUE!

How to use it?

Before starting let’s add some properties to the ViewModel:


In our XAML you just must add the MultiBinding to any property you want, specify the format using StringFormat by adding a {} to escape the sequence, add all the properties you want using {[sequenceNumber]} for each property.

<Button> <Button.Text> <MultiBinding StringFormat="{}{0} {1}"> <Binding Path="FirstName" /> <Binding Path="LastName" /> </MultiBinding> </Button.Text> </Button>



For each Binding, you can also specify a Converter, TargetNullValue, FallbackValue, TargetNullValue, etc.


How to use it with converters?

(If you are not familiar with converters, please read this article first).

There are two ways to do it:

  • Add it to the Multi-Binding property,
  • Add it to each Binding,

Add it to the Multi-Binding property

It will convert the list of bindings to the value we want to show. To achieve this, we will have to create our converters a little different than what we are used to doing.

Let’s create a converter that depending on the full name and a parameter allows us to know if that person is our cousin or not.

public class MultiBindingToCousinConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values != null && targetType.IsAssignableFrom(typeof(string)) && parameter != null) { if (values.Contains(parameter)) return $"Hello Cousin {string.Join(" ", values)}"; else return $"Hello {string.Join(" ", values)}"; }

return "Hello Stranger"; }

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }

As you see here, since we are converting a Multi-Binding to a single target value our converter needs to be a little bit different. Instead of extending from IValueConverter we will extend from IMultiValueConverter and we will receive an array with all the specified Bindings.

To use it:

<?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="MultiBinding.MainPage" xmlns:local="clr-namespace:MultiBinding.Converters"> <ContentPage.Resources> <ResourceDictionary> <local:MultiBindingToCousinConverter x:Key="MultiBindingToCousinConverter"/> </ResourceDictionary> </ContentPage.Resources>

<Button> <Button.Text> <MultiBinding Converter="{StaticResource MultiBindingToCousinConverter}" ConverterParameter="Agramonte"> <Binding Path="FirstName" /> <Binding Path="LastName" /> </MultiBinding> </Button.Text> </Button> </ContentPage>


With this approach, is quite easy to show/hide something based on multiple properties, for example:

<Button> <Button.IsVisible> <MultiBinding Converter="{StaticResource AllTrueConverter}"> <Binding Path="Employee.IsOver16" /> <Binding Path="Employee.HasPassedTest" /> <Binding Path="Employee.IsSuspended"/> </MultiBinding> </Button.IsChecked> </Button>

Check this full example here.

Add it to each Binding

Another way to use it is by applying individual converters to each binding, by using this approach we create our converters like we normally do.

For example, let’s apply converters: TextToUpper and TextToLower.

<?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="MultiBinding.MainPage" xmlns:local="clr-namespace:MultiBinding.Converters"> <ContentPage.Resources> <ResourceDictionary> <local:TextToUpperConverter x:Key="TextToUpperConverter"/> <local:TextToLowerConverter x:Key="TextToLowerConverter"/> </ResourceDictionary> </ContentPage.Resources> <Button> <Button.Text> <MultiBinding StringFormat="{}{0} {1}"> <Binding Path="FirstName" Converter="{StaticResource TextToUpperConverter}" /> <Binding Path="LastName" Converter="{StaticResource TextToLowerConverter}" /> </MultiBinding> </Button.Text> </Button> </ContentPage>


How to use it with Static Properties?

To use it with StaticProperty, you just need to make sure to use the Source in the Binding instead of the Path, as that text does not belong to the main Binding Source.

<?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="MultiBinding.MainPage" xmlns:local="clr-namespace:MultiBinding.Converters" xmlns:resource="clr-namespace:MultiBinding"> <Label> <Label.Text> <MultiBinding StringFormat="{}{0} {1} {2}"> <Binding Source="{x:Static resource:AppResources.Welcome}"/> <Binding Path="FirstName"/> <Binding Path="LastName"/> </MultiBinding> </Label.Text> </Label> </ContentPage>


That’s all for now, you can check the full source code here.

Happy coding!

Like this:


About Joyk

Aggregate valuable and interesting links.
Joyk means Joy of geeK