Home

Awesome

Xamarin.Forms Grid Markup Extension

🚨Experimental🚨.

Specify grid locations by name for simpler, more maintainable XAML.

Before

<Label Grid.Row="0" />

After

<Label Grid.Row="{local:GridLocation titleRow}"/>

See:

Using the GridLocation and GridSpan markup extensions

The Problem With Grids In Xamarin.Forms

Grids, while powerful, have one fundamental drawback; we place controls using 0-based indices. Consider the following code:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="2"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Label Grid.Row="0" /> <!-- Title label -->
    <ContentView Grid.Row="1" /> <!-- Content Divider-->
    <StackLayout Grid.Row="2"/> <!-- Content -->
    <ActivityIndicator Grid.RowSpan="3" /> <!-- Loading Indicator that covers all rows -->

</Grid>

Each time we place a control in the grid, we do so using a 0-based location. This has a few problems:

To solve these issues, this repository introduces two new markup extensions that allow grid locations to be referenced by name:

These extensions require that each row and column definition includes an x:Name attribute to expose it to the extension. For example: <RowDefinition x:Name="contentRow" Height=Auto/>.

Here is an example these extensions applied to the previous code sample:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition x:Name="titleRow"  Height="Auto"/>
        <RowDefinition x:Name="dividerRow" Height="2"/>
        <RowDefinition x:Name="contentRow" Height="*"/>
    </Grid.RowDefinitions>

    <Label Grid.Row="{local:GridLocation titleRow}" /> <!-- Title label -->
    <ContentView Grid.Row="{local:GridLocation dividerRow}" /> <!-- Content Divider-->
    <StackLayout Grid.Row="{local:GridLocation contentRow}"/> <!-- Content -->
    <ActivityIndicator Grid.RowSpan="{local:GridSpan From=titleRow, To=contentRow}" /> <!-- Loading Indicator that covers all rows -->

</Grid>

There are a few benefits here:

If you like this work and would like to see it continue, please raise an issue to start a discussion. 😊

Disclaimer

While stable and tested, it is not recommended that you use this code in your production apps for the following reasons: