How a simple row or column span can make or break your Xamarin.Forms Grid

Xamarin XAML

5 years ago

Today I will share a pretty surprising issue with you. It took me a while to debug and hence this article may save you a few minutes/hours when you encounter it too. The Xamarin.Forms Grid children can be laid out using properties Grid.Row, Grid.Column, Grid.RowSpan and Grid.ColumnSpan. It turns out that the Span properties are particularly dangerous if you don't manage them properly. Let me show you. Suppose the following simple layout:

To summarize the XAML - we have a root Grid which has two defined columns and three children. The third child of the Grid is a Frame which is horizontally centered within the Grid (its HorizontalOptions are set to Center). So let's run the app and see what happens:

Ouch. This is not really centered.

Ouch. This is not really centered.

The Frame is definitely not centered! It seems like the Grid does not have two * columns, but three. How is it possible? ColumnSpan magic. Notice the second child in the Grid:

It lies in the second column of the Grid, but its ColumnSpan is set to 2! Now, this would not matter in WPF and UWP where any "overflow" is ignored - in fact, I have seen some layouts which are counting on this behavior to simplify VisualState changes, etc. However, Xamarin.Forms handles this case differently. Instead of ignoring it actually "generates" a faux * sized column in our Grid. The Frame is then centered, but only in terms of the first two columns. Indeed, when we remove the Grid.ColumnSpan from the second BoxView, everything looks as expected:

Centered properly

Centered properly

Similar problems occur if we overflow the RowSpan property as well. This behavior comes to me as a surprise, and I presume it is more likely a bug than a feature, as you cannot create a "fake" column the same way by setting Grid.Column to a number outside of bounds. I am planning to report this to see if there is an official answer. Before then, we need to make sure our Spans have the right size so that we don't mysteriously break our Grid layouts.