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:
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:
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.