Cuadrícula

Browse sample. Examina el ejemplo

.NET MAUI Grid.

NET Multi-platform App UI (.NET MAUI) Grid, es un diseño que organiza los elementos secundarios en filas y columnas, que pueden tener tamaños proporcionales o absolutos. De forma predeterminada, las vistas Grid contienen una fila y una columna. Además, Grid se puede usar como diseño primario que contiene otros diseños secundarios.

Grid no debe confundirse con las tablas y no está pensado para presentar datos tabulares. A diferencia de las tablas HTML, Grid está pensada para diseñar contenido. Para mostrar datos tabulares, considera la posibilidad de usar ListView o CollectionView.

La clase Grid define las propiedades siguientes:

  • Column, de tipo int, que es una propiedad adjunta que indica la alineación de columna de una vista dentro de un elemento primario Grid. El valor predeterminado de esta propiedad es 0. Una devolución de llamada de validación garantiza que, cuando se establece la propiedad, su valor es mayor o igual que 0.
  • ColumnDefinitions, de tipo ColumnDefinitionCollection, es una lista de objetos ColumnDefinition que definen el ancho de las columnas de cuadrícula.
  • ColumnSpacing, de tipo double, indica la distancia entre las columnas de cuadrícula. El valor predeterminado de esta propiedad es 0.
  • ColumnSpan, de tipo int, que es una propiedad adjunta que indica el número total de columnas que abarca una vista dentro de un elemento primario Grid. El valor predeterminado de esta propiedad es 1. Una devolución de llamada de validación garantiza que, cuando se establece la propiedad, su valor es mayor o igual que 1.
  • Row, de tipo int, que es una propiedad adjunta que indica la alineación de fila de una vista dentro de un elemento primario Grid. El valor predeterminado de esta propiedad es 0. Una devolución de llamada de validación garantiza que, cuando se establece la propiedad, su valor es mayor o igual que 0.
  • RowDefinitions, de tipo RowDefinitionCollection, es una lista de objetos RowDefinition que definen la altura de las filas de cuadrícula.
  • RowSpacing, de tipo double, indica la distancia entre las filas de la cuadrícula. El valor predeterminado de esta propiedad es 0.
  • RowSpan, de tipo int, que es una propiedad adjunta que indica el número total de filas que abarca una vista dentro de un elemento primario Grid. El valor predeterminado de esta propiedad es 1. Una devolución de llamada de validación garantiza que, cuando se establece la propiedad, su valor es mayor o igual que 1.

Todas estas propiedades están respaldados por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos, y se les puede aplicar estilos.

En filas y columnas

De forma predeterminada, Grid contiene una fila y una columna:

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

En este ejemplo, Grid contiene un único elemento secundario Label que se coloca automáticamente en una sola ubicación:

Default .NET MAUI Grid layout.

El comportamiento de diseño de un objeto Grid se puede definir con las propiedades RowDefinitions y ColumnDefinitions, que son colecciones de objetos RowDefinition y ColumnDefinition, respectivamente. Estas colecciones definen las características de fila y columna de Grid y deben contener un objeto RowDefinition para cada fila de Grid y un objeto ColumnDefinition para cada columna de Grid.

La clase RowDefinition define una propiedad Height, de tipo GridLength y la clase ColumnDefinition define una propiedad Width de tipo GridLength. La estructura GridLength especifica una altura de fila o una anchura de columna en términos de la enumeración GridUnitType, que tiene tres miembros:

  • Absolute – el ancho o el alto se especifica en unidades independientes del dispositivo (un número en XAML).
  • Auto el alto o ancho se ajusta automáticamente según el contenido de la celda (Auto en XAML).
  • Star: el alto de fila o el ancho de columna izquierdo se asignan proporcionalmente (un número seguido de * en XAML).

Una fila Grid con una propiedad Height de Auto restringe la altura de las vistas de esa fila de la misma manera que StackLayout vertical. De forma similar, una columna con una propiedad Width de Auto funciona de forma muy similar a un StackLayout horizontal.

Precaución

Procura que el menor número posible de filas y columnas tengan el tamaño establecido en Auto. Cada fila o columna de tamaño automático hará que el motor de diseño tenga que realizar cálculos de diseño adicionales. En su lugar, use filas y columnas de tamaño fijo si es posible. Como alternativa, establece las filas y columnas para que ocupen una cantidad proporcional de espacio con el valor de enumeración GridUnitType.Star.

En el código XAML siguiente se muestra cómo crear un objeto Grid con tres filas y dos columnas:

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

En este ejemplo, Grid tiene una altura general que es la altura de la página. Grid sabe que la altura de la tercera fila es de 100 unidades independientes del dispositivo. Resta esa altura de su propia altura y asigna la altura restante proporcionalmente entre las primeras y las segundas filas en función del número delante del asterisco. En este ejemplo, la altura de la primera fila es dos veces la de la segunda fila.

Los dos objetos ColumnDefinition establecen Width en *, que es el mismo que 1*, lo que significa que la anchura de la pantalla se divide igualmente debajo de las dos columnas.

Importante

El valor predeterminado de la propiedad RowDefinition.Height es *. Asimismo, el valor predeterminado de la propiedad ColumnDefinition.Width es *. Por lo tanto, no es necesario establecer estas propiedades en los casos en que estos valores predeterminados sean aceptables.

Las vistas secundarias se pueden colocar en celdas Grid específicas con las propiedades adjuntas Grid.Column y Grid.Row. Además, para que las vistas secundarias abarquen varias filas y columnas, usa las propiedades adjuntas Grid.RowSpan y Grid.ColumnSpan.

El XAML siguiente muestra la misma definición Grid, y también coloca las vistas secundarias en celdas Grid específicas:

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

Nota:

Las propiedades Grid.Row y Grid.Column se indexan las dos desde 0, por lo que Grid.Row="2" hace referencia a la tercera fila mientras que Grid.Column="1" hace referencia a la segunda columna. Además, ambas propiedades tienen un valor predeterminado de 0, por lo que no es necesario establecerlas en vistas secundarias que ocupan la primera fila o la primera columna de Grid.

En este ejemplo, las tres filas Grid están ocupadas por las vistas BoxView y Label. La tercera fila tiene una altura de 100 unidades independientes del dispositivo, y las dos primeras filas ocupan el espacio restante (la primera fila tiene el doble de altura que la segunda). Las dos columnas tienen el mismo ancho y dividen el valor Grid por la mitad. BoxView en la tercera fila ocupa ambas columnas:

Basic .NET MAUI Grid layout.

Además, las vistas secundarias de Grid pueden compartir celdas. El orden en que aparecen los elementos secundarios en el XAML es el orden en que se colocan los elementos secundarios en Grid. En el ejemplo anterior, los objetos Label solo son visibles porque se representan encima de los objetos BoxView. Los objetos Label no serían visibles si los objetos BoxView se representaran encima de ellos.

El código de C# equivalente es el siguiente:

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;
    }
}

En el código, para especificar la altura de un objeto RowDefinition y la anchura de un objeto ColumnDefinition, se usan los valores de la estructura GridLength, a menudo en combinación con la enumeración GridUnitType.

Nota:

Grid también define un método de extensión AddWithSpan que agrega una vista a Grid en la fila y la columna especificadas con los intervalos de fila y columna especificados.

Simplificar definiciones de filas y columnas

En XAML, las características de fila y columna de Grid se pueden especificar con una sintaxis simplificada que evita tener que definir los objetos RowDefinition y ColumnDefinition para cada fila y columna. En su lugar, las propiedades RowDefinitions y ColumnDefinitions se pueden establecer en cadenas que contienen valores GridUnitType delimitados por comas, desde los cuales los convertidores de tipos integrados en .NET MAUI crean los objetos RowDefinition y ColumnDefinition:

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

En este ejemplo, Grid cinco filas y cuatro columnas. Las filas tercera, cuarta y quinta se establecen en alturas absolutas, mientras que la segunda ajusta el tamaño automáticamente a su contenido. Después, la altura restante se asigna a la primera fila.

La columna de salida se establece en una anchura absoluta, mientras que la tercera columna ajusta automáticamente su tamaño a su contenido. La anchura restante se asigna proporcionalmente entre las columnas primera y segunda basándose en el número delante del asterisco. En este ejemplo, la anchura de la segunda columna es dos veces la de la primera columna (porque * es idéntico a 1*).

Espacio entre filas y columnas

De forma predeterminada, las filas y columnas de Grid no tienen espacio entre ellas. Esto se puede cambiar estableciendo las propiedades RowSpacing y 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>

En este ejemplo se crea una Grid cuyas filas y columnas están separadas por 6 unidades de espacio independientes del dispositivo:

.NET MAUI Grid with spacing between cells.

Sugerencia

Las propiedades RowSpacing y ColumnSpacing se pueden establecer en valores negativos para que el contenido de la celda se superponga.

El código de C# equivalente es el siguiente:

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

        Content = grid;
    }
}

Alineación

Las vistas secundarias de un Grid se pueden colocar dentro de sus celdas con las propiedades HorizontalOptions y VerticalOptions. Estas propiedades se pueden establecer en los siguientes campos de la estructura LayoutOptions:

  • Start
  • Center
  • End
  • Fill

En el siguiente XAML se crea Grid con nueve celdas de mismo tamaño, y se coloca un elemento Label en cada celda con una alineación 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>

En este ejemplo, los objetos Label de cada fila están alineados verticalmente de forma idéntica, pero usan diferentes alineaciones horizontales. O bien, se puede considerar que los objetos Label de cada columna están alineados horizontalmente de forma idéntica, pero con diferentes alineaciones verticales:

Cell alignment in a .NET MAUI Grid.

El código de C# equivalente es el siguiente:

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 Grid anidados

Un objeto Grid se puede usar como diseño primario que contiene objetos Grid secundarios anidados u otros diseños secundarios. Al anidar objetos Grid, las propiedades adjuntas Grid.Row, Grid.Column, Grid.RowSpan y Grid.ColumnSpan siempre hacen referencia a la posición de las vistas dentro de su primario Grid.

El siguiente XAML muestra un ejemplo de objetos Grid de anidamiento:

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

En este ejemplo, la raíz Grid contiene un BoxView en su primera fila y un elemento secundario Grid en su segunda fila. El elemento secundario Grid contiene objetos Slider que manipulan el color mostrado por el BoxView, y objetos Label que muestran el valor de cada Slider:

Nested .NET MAUI Grid objects.

Importante

Cuanto más profundo anides objetos Grid y otros diseños, más cálculos de diseño se realizarán, lo que puede afectar al rendimiento. Para obtener más información, consulta Elegir el diseño correcto.

El código de C# equivalente es el siguiente:

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);
    }
}