Xamarin.Forms RowDefinition & ColumnDefinition through binding

Under one of my YouTube videos about the simplified grid RowDefinition and ColumnDefinition syntax, I got the question how to do this in with data-binding. In this post I will write about that so that everyone can benefit.

How To Databind the RowDefinition and ColumnDefinition

From some quick testing I don’t think there is an easy way to simply bind to strings, the type converter will not pick up on that. I will get back to this in a moment.

If you do want to do the binding, you will need to use the RowDefinitionCollection object. You will need to create an instance of that, and add instances of RowDefinition with the desired Height. Or, if you’re after columns, simply replace “row” with “column” and specify a width.

Underneath you can see a quick gist of what you need to put in your backing code and in your XAML. I think it’s self-explanatory, it not, please let me know 🙂

// MainPage.xaml.cs
public RowDefinitionCollection MyRows => new RowDefinitionCollection() {
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = 100 },
new RowDefinition { Height = GridLength.Star },
new RowDefinition { Height = 50 },
};
public MainPage()
{
InitializeComponent();
BindingContext = this;
}
// MainPage.xaml
<?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="TestSwitch.MainPage">
<Grid RowDefinitions="{Binding MyRows}">
<Frame Grid.Row="0" BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36" />
</Frame>
<Label Text="1" Grid.Row="1" />
<Label Text="2" Grid.Row="2" />
<Label Text="3" Grid.Row="3" />
</Grid>
</ContentPage>
view raw gistfile1.txt hosted with ❤ by GitHub

If you do want to use the simple string notation, you can leverage the RowDefinitionCollectionTypeConverter yourself. The code will then look something like this in the gist underneath.

// MainPage.xaml.cs
public RowDefinitionCollection MyRows { get; set; }
public MainPage()
{
InitializeComponent();
// Magic happening here
MyRows = (RowDefinitionCollection)new RowDefinitionCollectionTypeConverter().ConvertFromInvariantString("Auto, 100, *, 50");
BindingContext = this;
}
// MainPage.xaml
<?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="TestSwitch.MainPage">
<Grid RowDefinitions="{Binding MyRows}">
<Frame Grid.Row="0" BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36" />
</Frame>
<Label Text="1" Grid.Row="1" />
<Label Text="2" Grid.Row="2" />
<Label Text="3" Grid.Row="3" />
</Grid>
</ContentPage>
view raw gistfile1.txt hosted with ❤ by GitHub

What you do with this is create your own instance of the converter that is normally used when you go through setting the hardcoded value in XAML.

One Big Note

A last big note on this is, that while I provide this as an answer, you probably do not want to use this unless you have a very specific need for it. This breaks the idea of the MVVM pattern as you are now influencing UI elements from your backing code which is not what you want to do.

So, no guarantees from this code!