In this new post, I want to show you via a simple project how to use in MAUI FlexLayout with children with different sizes.
FlexLayout in MAUI is a layout that can arrange its children horizontally and vertically in a stack. Also, it wraps its children if there are too many children to fit in a single row or column. FlexLayout can control orientation and alignment, and adapt to different screen sizes.
The source code of this post is available on GitHub.
Create the value converters
StringToViewSizeStringConverter
Now, the first converter will help me with the FlexBasis which is an attached property that defines the initial main size of the child before free space is distributed according to other property values. The default value of this property is Auto
.
If the Entry text length is more than 1 then this converter will return 90% of FlexBasis else 100% FlexBasis.
public class StringToViewSizeStringConverter : IValueConverter
{
public StringToViewSizeStringConverter()
{
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string val = (string)value;
if (!string.IsNullOrEmpty(val))
{
return new FlexBasis(0.90f, true);
}
else
{
return new FlexBasis(1f, true);
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return !((bool)value);
}
}
StringToReverseBoolConverter
I want to apply this converter to the Entry in the UI. If the Entry has text (text length more than 1) then I want to display an icon. Here the simple implementation for checking the length of the Entry.
public class StringToReverseBoolConverter : IValueConverter
{
public StringToReverseBoolConverter()
{
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string val = (string)value;
if (!string.IsNullOrEmpty(val))
{
if (val.Length > 0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return !((bool)value);
}
}
The MainPage
Finally, I have to create the XAML to display the skills using a view model to manage the skills.
ViewModel
Now, the view model is quite simple. The property Skills
is collecting all the values the UI has to display.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MAUIFlexSkills.ViewModels
{
public class MainPageViewModel
{
private ObservableCollection<string>? _skills;
public MainPageViewModel()
{
Skills = new ObservableCollection<string>();
}
public ObservableCollection<string>? Skills
{
get
{
return _skills;
}
set
{
_skills = value;
}
}
}
}
XAML
Now, we can use those converters in the MainPage. So, add the reference to them and I call it converter
. Then, I call each of them, ready to be used.
<ContentPage
x:Class="MAUIFlexSkills.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:converter="clr-namespace:MAUIFlexSkills.ValueConverters">
<ContentPage.Resources>
<converter:StringToReverseBoolConverter x:Key="IsLableShow" />
<converter:StringToViewSizeStringConverter x:Key="ViewSizeConverter" />
</ContentPage.Resources>
Entry part
Then, you can start to add the Entry in a FlexLayout. When the user starts to type, an image of a check will be shown. If the user clicks on this image, the skill will be added to the list.
<FlexLayout Direction="Row" HeightRequest="50">
<Entry
x:Name="SkillEntry"
Margin="5"
FlexLayout.Basis="{Binding Source={x:Reference SkillEntry}, Path=Text, Converter={StaticResource ViewSizeConverter}}"
FontSize="20"
HeightRequest="50"
HorizontalOptions="FillAndExpand"
Keyboard="Text"
Placeholder="Add Skill"
VerticalOptions="Fill" />
<Image
x:Name="ImageCheck"
FlexLayout.AlignSelf="Center"
FlexLayout.Basis="10%"
HeightRequest="35"
IsVisible="{Binding Source={x:Reference SkillEntry}, Path=Text, Converter={StaticResource IsLableShow}}"
Source="check.png"
VerticalOptions="CenterAndExpand"
WidthRequest="35">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnAddSkillClicked" />
</Image.GestureRecognizers>
</Image>
</FlexLayout>
The result is as in the following screenshot, with and without a text value in the Entry.


- Direction=”Row“: Children will appear horizontally.
- For Entry, I have used StringToViewSizeStringConverter converter to manage the width size.
Display the skills
Then, this is the interesting part. Here I display the label for each skill and each of them has a different size.
<FlexLayout
x:Name="FlexSkillContainer"
Margin="5,-10,5,5"
AlignContent="Start"
AlignItems="Start"
BindableLayout.ItemsSource="{Binding Skills}"
Direction="Row"
HorizontalOptions="FillAndExpand"
JustifyContent="Start"
VerticalOptions="Fill"
Wrap="Wrap">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Frame
Margin="2"
Padding="4"
BackgroundColor="{StaticResource ColorFocused}"
CornerRadius="15">
<StackLayout Margin="5,0,5,0" Orientation="Horizontal">
<Label
x:Name="LabelSkill"
Margin="5,0,5,0"
FontSize="18"
Text="{Binding .}"
TextColor="{StaticResource ColorWhite}"
VerticalOptions="Center" />
<Image
x:Name="ImgCross"
HeightRequest="48"
HorizontalOptions="End"
Source="cross.png"
VerticalOptions="Center"
WidthRequest="48">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnDeleteSkillClicked" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
</Frame>
</DataTemplate>
</BindableLayout.ItemTemplate>
</FlexLayout>
I have used the properties in FlexLayout as follows:
- FlexLayout.Basis attached property to its children.
- FlexLayout.Basis, defines the amount of space that’s allocated to a child on the main axis.
- JustifyContent=“Start”: children will aligned from the start without any spacing.
- Wrap=”Wrap”: FlexLayout will wrap its children. If there are too many children to fit in a single row.

Wrap up
In conclusion, this is how to use FlexLayout with different sizes with a simple working example. Please contact me if you have any question or improvement.