Grid

Browse sample. Navegue pelo exemplo

.NET MAUI Grid.

O .NET Multi-platform App UI (.NET MAUI) Grid, é um layout que organiza seus filhos em linhas e colunas, que podem ter tamanhos proporcionais ou absolutos. Por padrão, a Grid contém uma linha e uma coluna. Além disso, um pode ser usado como um Grid layout pai que contém outros layouts filho.

O Grid não deve ser confundido com tabelas, e não se destina a apresentar dados tabulares. Ao contrário das tabelas HTML, a Grid destina-se ao layout do conteúdo. Para exibir dados tabulares, considere usar um ListView ou CollectionView.

A Grid classe define as seguintes propriedades:

  • Column, do tipo int, que é uma propriedade anexada que indica o alinhamento da coluna de um modo de exibição dentro de um pai Grid. O valor padrão dessa propriedade é 0. Um retorno de chamada de validação garante que, quando a propriedade é definida, seu valor é maior ou igual a 0.
  • ColumnDefinitions, do tipo ColumnDefinitionCollection, é uma lista de objetos que definem a largura das colunas de ColumnDefinition grade.
  • ColumnSpacing, do tipo double, indica a distância entre as colunas da grade. O valor padrão dessa propriedade é 0.
  • ColumnSpan, do tipo int, que é uma propriedade anexada que indica o número total de colunas que um modo de exibição abrange em um pai Grid. O valor padrão desta propriedade é 1. Um retorno de chamada de validação garante que, quando a propriedade é definida, seu valor é maior ou igual a 1.
  • Row, do tipo int, que é uma propriedade anexada que indica o alinhamento da linha de um modo de exibição dentro de um pai Grid. O valor padrão dessa propriedade é 0. Um retorno de chamada de validação garante que, quando a propriedade é definida, seu valor é maior ou igual a 0.
  • RowDefinitions, do tipo RowDefinitionCollection, é uma lista de RowDefinition objetos que definem a altura das linhas da grade.
  • RowSpacing, do tipo double, indica a distância entre as linhas da grade. O valor padrão dessa propriedade é 0.
  • RowSpan, do tipo int, que é uma propriedade anexada que indica o número total de linhas que um modo de exibição abrange em um pai Grid. O valor padrão desta propriedade é 1. Um retorno de chamada de validação garante que, quando a propriedade é definida, seu valor é maior ou igual a 1.

Essas propriedades são apoiadas por BindableProperty objetos, o que significa que as propriedades podem ser alvos de associações de dados e estilizadas.

Linhas e colunas

Por padrão, um Grid contém uma linha e uma coluna:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridTutorial.MainPage">
    <Grid Margin="20,35,20,20">
        <Label Text="By default, a Grid contains one row and one column." />
    </Grid>
</ContentPage>

Neste exemplo, o contém um único filho Label que é posicionado Grid automaticamente em um único local:

Default .NET MAUI Grid layout.

O comportamento de layout de um Grid pode ser definido com as RowDefinitions propriedades e , que são coleções de RowDefinition e ColumnDefinitionsColumnDefinition objetos, respectivamente. Essas coleções definem as características de linha e coluna de um , e devem conter um objeto para cada linha no Grid, e um ColumnDefinitionGridRowDefinition objeto para cada coluna no Grid.

A RowDefinition classe define uma propriedade, do tipo , e a ColumnDefinition classe define uma WidthHeight propriedade, do tipo GridLengthGridLength. A GridLength struct especifica uma altura de linha ou uma largura de coluna em termos de GridUnitType enumeração, que tem três membros:

  • Absolute – a altura da linha ou largura da coluna é um valor em unidades independentes do dispositivo (um número em XAML).
  • Auto – a altura da linha ou da coluna é dimensionada automaticamente com base no conteúdo da célula (Auto em XAML).
  • Star – a altura restante da linha ou da coluna é alocada proporcionalmente (um número seguido de * XAML).

Uma Grid linha com uma propriedade de Auto restringe a altura das exibições nessa linha da mesma forma que uma Height vertical StackLayout. Da mesma forma, uma coluna com uma propriedade de Auto funciona muito como uma Width horizontal StackLayout.

Cuidado

Tente garantir que o menor número possível de linhas e colunas esteja definido para Auto o tamanho. Cada linha ou coluna dimensionada automaticamente fará o mecanismo de layout realizar cálculos de layout adicionais. Em vez disso, use linhas e colunas de tamanho fixo, se possível. Como alternativa, defina linhas e colunas para ocupar uma quantidade proporcional de espaço com o GridUnitType.Star valor de enumeração.

O XAML a seguir mostra como criar um Grid com três linhas e duas colunas:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridDemos.Views.XAML.BasicGridPage"
             Title="Basic Grid demo">
   <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        ...
    </Grid>
</ContentPage>

Neste exemplo, o Grid tem uma altura geral que é a altura da página. A Grid altura da terceira fileira é de 100 unidades independentes de dispositivos. Ele subtrai essa altura de sua própria altura, e aloca a altura restante proporcionalmente entre a primeira e a segunda fileiras com base no número antes da estrela. Neste exemplo, a altura da primeira linha é o dobro da segunda linha.

Os dois ColumnDefinition objetos definem o como *, que é o mesmo 1*que , o Width que significa que a largura da tela é dividida igualmente abaixo das duas colunas.

Importante

O valor padrão da RowDefinition.Height propriedade é *. Da mesma forma, o ColumnDefinition.Width valor padrão da propriedade é *. Portanto, não é necessário definir essas propriedades nos casos em que esses padrões são aceitáveis.

As exibições filho podem ser posicionadas em células específicas Grid com as Grid.Column propriedades e Grid.Row anexadas. Além disso, para fazer com que os modos de exibição filho se estendam por várias linhas e colunas, use as Grid.RowSpan propriedades e Grid.ColumnSpan anexadas.

O XAML a seguir mostra a mesma Grid definição e também posiciona modos de exibição filho em células específicas Grid :

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridDemos.Views.XAML.BasicGridPage"
             Title="Basic Grid demo">
   <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*" />
            <RowDefinition />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <BoxView Color="Green" />
        <Label Text="Row 0, Column 0"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <BoxView Grid.Column="1"
                 Color="Blue" />
        <Label Grid.Column="1"
               Text="Row 0, Column 1"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <BoxView Grid.Row="1"
                 Color="Teal" />
        <Label Grid.Row="1"
               Text="Row 1, Column 0"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <BoxView Grid.Row="1"
                 Grid.Column="1"
                 Color="Purple" />
        <Label Grid.Row="1"
               Grid.Column="1"
               Text="Row1, Column 1"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <BoxView Grid.Row="2"
                 Grid.ColumnSpan="2"
                 Color="Red" />
        <Label Grid.Row="2"
               Grid.ColumnSpan="2"
               Text="Row 2, Columns 0 and 1"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
    </Grid>
</ContentPage>

Observação

As Grid.Row propriedades e são indexadas a partir de 0 e Grid.Column , portanto Grid.Row="2" , referem-se à terceira linha, enquanto Grid.Column="1" se referem à segunda coluna. Além disso, ambas as propriedades têm um valor padrão de 0 e, portanto, não precisam ser definidas em exibições filho que ocupam a primeira linha ou a primeira coluna de um Gridarquivo .

Neste exemplo, todas as três Grid linhas são ocupadas por BoxView e Label modos de exibição. A terceira linha tem 100 unidades independentes de dispositivo, com as duas primeiras linhas ocupando o espaço restante (a primeira fileira tem o dobro da altura da segunda linha). As duas colunas são iguais em largura e dividem a Grid ao meio. A BoxView terceira linha abrange ambas as colunas:

Basic .NET MAUI Grid layout.

Além disso, as exibições filho em um Grid podem compartilhar células. A ordem em que os filhos aparecem no XAML é a ordem em que os filhos são colocados no Grid. No exemplo anterior, os objetos só são visíveis porque são renderizados sobre os LabelBoxView objetos. Os Label objetos não seriam visíveis se os BoxView objetos fossem renderizados sobre eles.

Este é o código C# equivalente:

public class BasicGridPage : ContentPage
{
    public BasicGridPage()
    {
        Grid grid = new Grid
        {
            RowDefinitions =
            {
                new RowDefinition { Height = new GridLength(2, GridUnitType.Star) },
                new RowDefinition(),
                new RowDefinition { Height = new GridLength(100) }
            },
            ColumnDefinitions =
            {
                new ColumnDefinition(),
                new ColumnDefinition()
            }
        };

        // Row 0
        // The BoxView and Label are in row 0 and column 0, and so only need to be added to the
        // Grid to obtain the default row and column settings.
        grid.Add(new BoxView
        {
            Color = Colors.Green
        });
        grid.Add(new Label
        {
            Text = "Row 0, Column 0",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        });

        // This BoxView and Label are in row 0 and column 1, which are specified as arguments
        // to the Add method.
        grid.Add(new BoxView
        {
            Color = Colors.Blue
        }, 1, 0);
        grid.Add(new Label
        {
            Text = "Row 0, Column 1",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        }, 1, 0);

        // Row 1
        // This BoxView and Label are in row 1 and column 0, which are specified as arguments
        // to the Add method overload.
        grid.Add(new BoxView
        {
            Color = Colors.Teal
        }, 0, 1);
        grid.Add(new Label
        {
            Text = "Row 1, Column 0",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        }, 0, 1);

        // This BoxView and Label are in row 1 and column 1, which are specified as arguments
        // to the Add method overload.
        grid.Add(new BoxView
        {
            Color = Colors.Purple
        }, 1, 1);
        grid.Add(new Label
        {
            Text = "Row1, Column 1",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        }, 1, 1);

        // Row 2
        // Alternatively, the BoxView and Label can be positioned in cells with the Grid.SetRow
        // and Grid.SetColumn methods. Here, the Grid.SetColumnSpan method is used to span two columns.
        BoxView boxView = new BoxView { Color = Colors.Red };
        Grid.SetRow(boxView, 2);
        Grid.SetColumnSpan(boxView, 2);
        Label label = new Label
        {
            Text = "Row 2, Column 0 and 1",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        };
        Grid.SetRow(label, 2);
        Grid.SetColumnSpan(label, 2);

        grid.Add(boxView);
        grid.Add(label);

        Title = "Basic Grid demo";
        Content = grid;
    }
}

No código, para especificar a altura de um objeto e a largura de um RowDefinitionColumnDefinition objeto, você usa valores da GridLength estrutura, geralmente em combinação com a GridUnitType enumeração.

Observação

GridTambém define um método de extensão que adiciona um modo de exibição à Grid linha e coluna especificadas com as extensões de AddWithSpan linha e coluna especificadas.

Simplificar definições de linha e coluna

Em XAML, as características de linha e coluna de um Grid podem ser especificadas usando uma sintaxe simplificada que evita a necessidade de definir RowDefinition e objetos para cada linha e ColumnDefinition coluna. Em vez disso, as propriedades e podem ser definidas como cadeias de caracteres contendo valores delimitados GridUnitType por vírgula, a RowDefinitions partir dos quais os conversores de tipo internos ao .NET MAUI criam RowDefinition e ColumnDefinitionsColumnDefinition objetos:

<Grid RowDefinitions="1*, Auto, 25, 14, 20"
      ColumnDefinitions="*, 2*, Auto, 300">
    ...
</Grid>

Neste exemplo, o Grid tem cinco linhas e quatro colunas. A terceira, quarta e quinta linhas são definidas para alturas absolutas, com a segunda linha dimensionando automaticamente para seu conteúdo. A altura restante é então alocada para a primeira linha.

A quarta coluna é definida como uma largura absoluta, com a terceira coluna dimensionada automaticamente para seu conteúdo. A largura restante é alocada proporcionalmente entre a primeira e a segunda colunas com base no número antes da estrela. Neste exemplo, a largura da segunda coluna é o dobro da primeira coluna (porque * é idêntica a 1*).

Espaço entre linhas e colunas

Por padrão, Grid linhas e colunas não têm espaço entre elas. Isso pode ser alterado definindo as RowSpacing propriedades e ColumnSpacing , respectivamente:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridDemos.Views.XAML.GridSpacingPage"
             Title="Grid spacing demo">
    <Grid RowSpacing="6"
          ColumnSpacing="6">
        ...
    </Grid>
</ContentPage>

Este exemplo cria cujas Grid linhas e colunas são separadas por 6 unidades de espaço independentes de dispositivo:

.NET MAUI Grid with spacing between cells.

Dica

As RowSpacing propriedades e ColumnSpacing podem ser definidas como valores negativos para fazer com que o conteúdo da célula se sobreponha.

Este é o código C# equivalente:

public class GridSpacingPage : ContentPage
{
    public GridSpacingPage()
    {
        Grid grid = new Grid
        {
            RowSpacing = 6,
            ColumnSpacing = 6,
            ...
        };
        ...

        Content = grid;
    }
}

Alinhamento

As exibições filho em um Grid podem ser posicionadas dentro de HorizontalOptions suas células pelas propriedades e VerticalOptions . Essas propriedades podem ser definidas para os seguintes campos da LayoutOptions struct:

  • Start
  • Center
  • End
  • Fill

O XAML a seguir cria um com nove células de tamanho igual e coloca um em cada célula com um GridLabel alinhamento diferente:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridDemos.Views.XAML.GridAlignmentPage"
             Title="Grid alignment demo">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <BoxView Color="AliceBlue" />
        <Label Text="Upper left"
               HorizontalOptions="Start"
               VerticalOptions="Start" />
        <BoxView Grid.Column="1"
                 Color="LightSkyBlue" />
        <Label Grid.Column="1"
               Text="Upper center"
               HorizontalOptions="Center"
               VerticalOptions="Start"/>
        <BoxView Grid.Column="2"
                 Color="CadetBlue" />
        <Label Grid.Column="2"
               Text="Upper right"
               HorizontalOptions="End"
               VerticalOptions="Start" />
        <BoxView Grid.Row="1"
                 Color="CornflowerBlue" />
        <Label Grid.Row="1"
               Text="Center left"
               HorizontalOptions="Start"
               VerticalOptions="Center" />
        <BoxView Grid.Row="1"
                 Grid.Column="1"
                 Color="DodgerBlue" />
        <Label Grid.Row="1"
               Grid.Column="1"
               Text="Center center"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <BoxView Grid.Row="1"
                 Grid.Column="2"
                 Color="DarkSlateBlue" />
        <Label Grid.Row="1"
               Grid.Column="2"
               Text="Center right"
               HorizontalOptions="End"
               VerticalOptions="Center" />
        <BoxView Grid.Row="2"
                 Color="SteelBlue" />
        <Label Grid.Row="2"
               Text="Lower left"
               HorizontalOptions="Start"
               VerticalOptions="End" />
        <BoxView Grid.Row="2"
                 Grid.Column="1"
                 Color="LightBlue" />
        <Label Grid.Row="2"
               Grid.Column="1"
               Text="Lower center"
               HorizontalOptions="Center"
               VerticalOptions="End" />
        <BoxView Grid.Row="2"
                 Grid.Column="2"
                 Color="BlueViolet" />
        <Label Grid.Row="2"
               Grid.Column="2"
               Text="Lower right"
               HorizontalOptions="End"
               VerticalOptions="End" />
    </Grid>
</ContentPage>

Neste exemplo, os Label objetos em cada linha são todos alinhados verticalmente de forma idêntica, mas usam alinhamentos horizontais diferentes. Alternativamente, isso pode ser pensado como os Label objetos em cada coluna sendo alinhados horizontalmente de forma idêntica, mas usando alinhamentos verticais diferentes:

Cell alignment in a .NET MAUI Grid.

Este é o código C# equivalente:

public class GridAlignmentPage : ContentPage
{
    public GridAlignmentPage()
    {
        Grid grid = new Grid
        {
            RowDefinitions =
            {
                new RowDefinition(),
                new RowDefinition(),
                new RowDefinition()
            },
            ColumnDefinitions =
            {
                new ColumnDefinition(),
                new ColumnDefinition(),
                new ColumnDefinition()
            }
        };

        // Row 0
        grid.Add(new BoxView
        {
            Color = Colors.AliceBlue
        });
        grid.Add(new Label
        {
            Text = "Upper left",
            HorizontalOptions = LayoutOptions.Start,
            VerticalOptions = LayoutOptions.Start
        });

        grid.Add(new BoxView
        {
            Color = Colors.LightSkyBlue
        }, 1, 0);
        grid.Add(new Label
        {
            Text = "Upper center",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Start
        }, 1, 0);

        grid.Add(new BoxView
        {
            Color = Colors.CadetBlue
        }, 2, 0);
        grid.Add(new Label
        {
            Text = "Upper right",
            HorizontalOptions = LayoutOptions.End,
            VerticalOptions = LayoutOptions.Start
        }, 2, 0);

        // Row 1
        grid.Add(new BoxView
        {
            Color = Colors.CornflowerBlue
        }, 0, 1);
        grid.Add(new Label
        {
            Text = "Center left",
            HorizontalOptions = LayoutOptions.Start,
            VerticalOptions = LayoutOptions.Center
        }, 0, 1);

        grid.Add(new BoxView
        {
            Color = Colors.DodgerBlue
        }, 1, 1);
        grid.Add(new Label
        {
            Text = "Center center",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        }, 1, 1);

        grid.Add(new BoxView
        {
            Color = Colors.DarkSlateBlue
        }, 2, 1);
        grid.Add(new Label
        {
            Text = "Center right",
            HorizontalOptions = LayoutOptions.End,
            VerticalOptions = LayoutOptions.Center
        }, 2, 1);

        // Row 2
        grid.Add(new BoxView
        {
            Color = Colors.SteelBlue
        }, 0, 2);
        grid.Add(new Label
        {
            Text = "Lower left",
            HorizontalOptions = LayoutOptions.Start,
            VerticalOptions = LayoutOptions.End
        }, 0, 2);

        grid.Add(new BoxView
        {
            Color = Colors.LightBlue
        }, 1, 2);
        grid.Add(new Label
        {
            Text = "Lower center",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.End
        }, 1, 2);

        grid.Add(new BoxView
        {
            Color = Colors.BlueViolet
        }, 2, 2);
        grid.Add(new Label
        {
            Text = "Lower right",
            HorizontalOptions = LayoutOptions.End,
            VerticalOptions = LayoutOptions.End
        }, 2, 2);

        Title = "Grid alignment demo";
        Content = grid;
    }
}

Objetos de grade aninhados

Um Grid pode ser usado como um layout pai que contém objetos filho aninhados ou outros layouts filho Grid . Ao aninhar Grid objetos, as Grid.Rowpropriedades , , Grid.ColumnGrid.RowSpane Grid.ColumnSpan anexadas sempre se referem à posição dos modos de exibição em seu paiGrid.

O XAML a seguir mostra um exemplo de aninhamento Grid de objetos:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:converters="clr-namespace:GridDemos.Converters"
             x:Class="GridDemos.Views.XAML.ColorSlidersGridPage"
             Title="Nested Grids demo">

    <ContentPage.Resources>
        <converters:DoubleToIntConverter x:Key="doubleToInt" />

        <Style TargetType="Label">
            <Setter Property="HorizontalTextAlignment"
                    Value="Center" />
        </Style>
    </ContentPage.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="500" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <BoxView x:Name="boxView"
                 Color="Black" />
        <Grid Grid.Row="1"
              Margin="20">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Slider x:Name="redSlider"
                    ValueChanged="OnSliderValueChanged" />
            <Label Grid.Row="1"
                   Text="{Binding Source={x:Reference redSlider},
                                  Path=Value,
                                  Converter={StaticResource doubleToInt},
                                  ConverterParameter=255,
                                  StringFormat='Red = {0}'}" />
            <Slider x:Name="greenSlider"
                    Grid.Row="2"
                    ValueChanged="OnSliderValueChanged" />
            <Label Grid.Row="3"
                   Text="{Binding Source={x:Reference greenSlider},
                                  Path=Value,
                                  Converter={StaticResource doubleToInt},
                                  ConverterParameter=255,
                                  StringFormat='Green = {0}'}" />
            <Slider x:Name="blueSlider"
                    Grid.Row="4"
                    ValueChanged="OnSliderValueChanged" />
            <Label Grid.Row="5"
                   Text="{Binding Source={x:Reference blueSlider},
                                  Path=Value,
                                  Converter={StaticResource doubleToInt},
                                  ConverterParameter=255,
                                  StringFormat='Blue = {0}'}" />
        </Grid>
    </Grid>
</ContentPage>

Neste exemplo, a raiz Grid contém um em sua primeira linha e um BoxView filho Grid em sua segunda linha. O filho Grid contém Slider objetos que manipulam a cor exibida pelo BoxView, e Label objetos que exibem o valor de cada Slider:

Nested .NET MAUI Grid objects.

Importante

Quanto mais profundo você aninhar Grid objetos e outros layouts, mais cálculos de layout serão executados, o que pode afetar o desempenho. Para obter mais informações, consulte Escolher o layout correto.

Este é o código C# equivalente:

public class ColorSlidersGridPage : ContentPage
{
    BoxView boxView;
    Slider redSlider;
    Slider greenSlider;
    Slider blueSlider;

    public ColorSlidersGridPage()
    {
        // Create an implicit style for the Labels
        Style labelStyle = new Style(typeof(Label))
        {
            Setters =
            {
                new Setter { Property = Label.HorizontalTextAlignmentProperty, Value = TextAlignment.Center }
            }
        };
        Resources.Add(labelStyle);

        // Root page layout
        Grid rootGrid = new Grid
        {
            RowDefinitions =
            {
                new RowDefinition { HeightRequest = 500 },
                new RowDefinition()
            }
        };

        boxView = new BoxView { Color = Colors.Black };
        rootGrid.Add(boxView);

        // Child page layout
        Grid childGrid = new Grid
        {
            Margin = new Thickness(20),
            RowDefinitions =
            {
                new RowDefinition(),
                new RowDefinition(),
                new RowDefinition(),
                new RowDefinition(),
                new RowDefinition(),
                new RowDefinition()
            }
        };

        DoubleToIntConverter doubleToInt = new DoubleToIntConverter();

        redSlider = new Slider();
        redSlider.ValueChanged += OnSliderValueChanged;
        childGrid.Add(redSlider);

        Label redLabel = new Label();
        redLabel.SetBinding(Label.TextProperty, new Binding("Value", converter: doubleToInt, converterParameter: "255", stringFormat: "Red = {0}", source: redSlider));
        Grid.SetRow(redLabel, 1);
        childGrid.Add(redLabel);

        greenSlider = new Slider();
        greenSlider.ValueChanged += OnSliderValueChanged;
        Grid.SetRow(greenSlider, 2);
        childGrid.Add(greenSlider);

        Label greenLabel = new Label();
        greenLabel.SetBinding(Label.TextProperty, new Binding("Value", converter: doubleToInt, converterParameter: "255", stringFormat: "Green = {0}", source: greenSlider));
        Grid.SetRow(greenLabel, 3);
        childGrid.Add(greenLabel);

        blueSlider = new Slider();
        blueSlider.ValueChanged += OnSliderValueChanged;
        Grid.SetRow(blueSlider, 4);
        childGrid.Add(blueSlider);

        Label blueLabel = new Label();
        blueLabel.SetBinding(Label.TextProperty, new Binding("Value", converter: doubleToInt, converterParameter: "255", stringFormat: "Blue = {0}", source: blueSlider));
        Grid.SetRow(blueLabel, 5);
        childGrid.Add(blueLabel);

        // Place the child Grid in the root Grid
        rootGrid.Add(childGrid, 0, 1);

        Title = "Nested Grids demo";
        Content = rootGrid;
    }

    void OnSliderValueChanged(object sender, ValueChangedEventArgs e)
    {
        boxView.Color = new Color(redSlider.Value, greenSlider.Value, blueSlider.Value);
    }
}