Поделиться через


Xamarin.Forms Сетка

Xamarin.Forms Сетка

Это Grid макет, который упорядочивает дочерние элементы в строки и столбцы, которые могут иметь пропорциональные или абсолютные размеры. По умолчанию Grid содержит одну строку и один столбец. Кроме того, Grid можно использовать в качестве родительского макета, содержащего другие дочерние макеты.

Макет Grid не следует путать с таблицами и не предназначен для представления табличных данных. В отличие от HTML-таблиц, Grid он предназначен для размещения содержимого. Для отображения табличных данных рекомендуется использовать ListView, CollectionView или TableView.

Класс Grid определяет следующие свойства:

  • ColumnintТип , который является присоединенным свойством, указывающим выравнивание столбцов представления в родительском Gridэлементе. Значение этого свойства по умолчанию равно 0. Обратный вызов проверки гарантирует, что при установке свойства его значение больше или равно 0.
  • ColumnDefinitionsColumnDefinitionCollectionТип — это список объектов, определяющих ColumnDefinition ширину столбцов сетки.
  • ColumnSpacingdoubleТип , указывает расстояние между столбцами сетки. Значение по умолчанию этого свойства — 6 единиц, независимых от устройства.
  • ColumnSpanintТип , который является присоединенным свойством, указывающим общее количество столбцов, охватывающих представление в родительском объектеGrid. Значение этого свойства по умолчанию равно 1. Обратный вызов проверки гарантирует, что при установке свойства его значение больше или равно 1.
  • RowintТип , который является присоединенным свойством, которое указывает выравнивание строк представления в родительском элементеGrid. Значение этого свойства по умолчанию равно 0. Обратный вызов проверки гарантирует, что при установке свойства его значение больше или равно 0.
  • RowDefinitionsRowDefinitionCollectionТип — это список объектов, определяющих RowDefintion высоту строк сетки.
  • RowSpacingdoubleТип , указывает расстояние между строками сетки. Значение по умолчанию этого свойства — 6 единиц, независимых от устройства.
  • RowSpanintТип , который является присоединенным свойством, указывающим общее количество строк, охватываемых представлением в родительском объектеGrid. Значение этого свойства по умолчанию равно 1. Обратный вызов проверки гарантирует, что при установке свойства его значение больше или равно 1.

Эти свойства поддерживаются объектами, что означает, что свойства могут быть целевыми BindableProperty объектами привязки данных и стилем.

Класс Grid является производным от Layout<T> класса, который определяет Children свойство типа IList<T>. Свойство Children является ContentProperty классом Layout<T> , поэтому не требуется явно задавать из XAML.

Совет

Чтобы получить оптимальную производительность макета, следуйте рекомендациям по оптимизации производительности макета.

Строки и столбцы

По умолчанию содержит Grid одну строку и один столбец:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             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>

В этом примере содержит один дочерний элементLabel, Grid который автоматически размещается в одном расположении:

Снимок экрана: макет сетки по умолчанию

Поведение макета Grid можно определить с помощью RowDefinitions свойств и ColumnDefinitions коллекций RowDefinition и ColumnDefinition объектов соответственно. Эти коллекции определяют характеристики строк и столбцов Gridи должны содержать один RowDefinition объект для каждой строки в строке Gridи один ColumnDefinition объект для каждого столбца в столбце Grid.

Класс RowDefinition определяет Height свойство, тип GridLengthи ColumnDefinition класс определяет Width свойство типа GridLength. Структуру GridLength задает высоту строки или ширину столбца GridUnitType с точки зрения перечисления, которая содержит три элемента:

  • Absolute — высота строки или ширина столбца — это значение в единицах, независимых от устройства (число в XAML).
  • Auto — высота строки или ширина столбца автоматически определяется с учетом содержимого ячейки (Auto в XAML).
  • Star — слева высота строки или ширина столбца выделяется пропорционально (число, * за которым следует в XAML).

Grid Строка со свойством Height Auto ограничивает высоту представлений в этой строке так же, как вертикальнаяStackLayout. Аналогичным образом столбец со свойством Width Auto работает так же, как горизонтальная StackLayout.

Внимание

Попробуйте убедиться, что для Auto размера задано максимальное количество строк и столбцов. Из-за каждой строки или столбца с автоматическим размером обработчик макета будет выполнять дополнительные вычисления макета. Если возможно, используйте строки и столбцы фиксированного размера. Кроме того, задайте для строк и столбцов пропорциональный объем пространства со GridUnitType.Star значением перечисления.

В следующем XAML показано, как создать Grid с тремя строками и двумя столбцами:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridDemos.Views.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>

В этом примере Grid имеет общую высоту страницы. Знает Grid , что высота третьей строки составляет 100 единиц, независимых от устройства. Он вычитает высоту из собственной высоты и выделяет оставшуюся высоту пропорционально между первой и второй строками на основе числа перед звездой. В этом примере высота первой строки в два раза превышает высоту второй строки.

Оба ColumnDefinition объекта задают Width *значение , что 1*совпадает с тем, что ширина экрана разделена одинаково под двумя столбцами.

Внимание

Значение RowDefinition.Height свойства по умолчанию — *. Аналогичным образом значение ColumnDefinition.Width свойства по умолчанию равно *. Поэтому не обязательно задавать эти свойства в случаях, когда эти значения по умолчанию допустимы.

Дочерние представления можно размещать в определенных Grid ячейках со Grid.Column свойствами и Grid.Row присоединенными свойствами. Кроме того, чтобы сделать дочерние представления диапазоном между несколькими строками и столбцами, используйте Grid.RowSpan Grid.ColumnSpan и присоединенные свойства.

В следующем коде XAML показано то же Grid определение, а также положение дочерних представлений в определенных Grid ячейках:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridDemos.Views.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>

Примечание.

И Grid.Row Grid.Column свойства индексируются от 0, и поэтому Grid.Row="2" ссылается на третью строку во время Grid.Column="1" ссылки на второй столбец. Кроме того, оба этих свойства имеют значение по умолчанию 0, поэтому не нужно задавать дочерние представления, которые занимают первую строку или первый столбец Grid.

В этом примере все три Grid строки занимаются представлениямиBoxView.Label Третья строка составляет 100 единиц, независимых от устройства, при этом первые две строки занимают оставшееся пространство (первая строка в два раза выше, чем вторая строка). Два столбца равны по ширине и делятся Grid на половину. В BoxView третьей строке оба столбца охватываются.

Снимок экрана: базовый макет сетки

Кроме того, дочерние Grid представления в ячейках могут совместно использовать. Порядок отображения дочерних элементов в XAML — это порядок, в который помещаются Gridдочерние элементы. В предыдущем примере объекты отображаются только из-за того, Label что они отображаются на вершине BoxView объектов. Объекты Label не будут видны, если BoxView объекты были отрисованы поверх них.

Эквивалентный код на C# выглядит так:

public class BasicGridPageCS : ContentPage
{
    public BasicGridPageCS()
    {
        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 needs to be added to the
        // Grid.Children collection to get default row and column settings.
        grid.Children.Add(new BoxView
        {
            Color = Color.Green
        });
        grid.Children.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.Children.Add(new BoxView
        {
            Color = Color.Blue
        }, 1, 0);
        grid.Children.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.Children.Add(new BoxView
        {
            Color = Color.Teal
        }, 0, 1, 1, 2);
        grid.Children.Add(new Label
        {
            Text = "Row 1, Column 0",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        }, 0, 1, 1, 2); // These arguments indicate that that the child element goes in the column starting at 0 but ending before 1.
                        // They also indicate that the child element goes in the row starting at 1 but ending before 2.

        grid.Children.Add(new BoxView
        {
            Color = Color.Purple
        }, 1, 2, 1, 2);
        grid.Children.Add(new Label
        {
            Text = "Row1, Column 1",
            HorizontalOptions = LayoutOptions.Center,
            VerticalOptions = LayoutOptions.Center
        }, 1, 2, 1, 2);

        // Row 2
        // Alternatively, the BoxView and Label can be positioned in cells with the Grid.SetRow
        // and Grid.SetColumn methods.
        BoxView boxView = new BoxView { Color = Color.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.Children.Add(boxView);
        grid.Children.Add(label);

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

В коде для указания высоты RowDefinition объекта и ширины ColumnDefinition объекта используются значения GridLength структуры, часто в сочетании с GridUnitType перечислением.

Приведенный выше пример кода также показывает несколько различных подходов к добавлению дочерних элементов Gridв ячейки, в которых они находятся. При использовании перегрузки, указывающей левыеAdd, правые, верхние и нижние аргументы, в то время как левые и верхние аргументы всегда будут ссылаться на ячейки внутри Grid, правые и нижние аргументы отображаются для ссылок на ячейки, которые находятся за пределамиGrid. Это связано с тем, что правый аргумент всегда должен быть больше левого аргумента, а нижний аргумент всегда должен быть больше верхнего аргумента. В следующем примере, который предполагает 2x2 Grid, показан эквивалентный код с использованием обоих Add перегрузок:

// left, top
grid.Children.Add(topLeft, 0, 0);           // first column, first row
grid.Children.Add(topRight, 1, 0);          // second column, first tow
grid.Children.Add(bottomLeft, 0, 1);        // first column, second row
grid.Children.Add(bottomRight, 1, 1);       // second column, second row

// left, right, top, bottom
grid.Children.Add(topLeft, 0, 1, 0, 1);     // first column, first row
grid.Children.Add(topRight, 1, 2, 0, 1);    // second column, first tow
grid.Children.Add(bottomLeft, 0, 1, 1, 2);  // first column, second row
grid.Children.Add(bottomRight, 1, 2, 1, 2); // second column, second row

Примечание.

Кроме того, дочерние представления можно добавить в Grid коллекцию с AddHorizontal помощью методов, AddVertical которые добавляют дочерние элементы в одну строку или один столбец Grid. Затем Grid выполняется развертывание строк или столбцов по мере выполнения этих вызовов, а также автоматическое размещение дочерних элементов в правильных ячейках.

Упрощение определений строк и столбцов

В XAML характеристики строки и столбца Grid можно указать с помощью упрощенного синтаксиса, который позволяет избежать необходимости определять и ColumnDefinition объекты RowDefinition для каждой строки и столбца. Вместо этого RowDefinitions ColumnDefinitions можно задать строки, содержащие значения с разделителями-запятыми GridUnitType , из которых преобразователи типов, встроенные в Xamarin.Forms создание RowDefinition и ColumnDefinition объекты:

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

В этом примере Grid имеется пять строк и четыре столбца. Третий, четвертый и пятый строки имеют абсолютные высоты, при этом вторая строка автоматически определяет размер содержимого. Оставшаяся высота затем выделяется первой строке.

Четвертый столбец имеет абсолютную ширину с автоматическим изменением размера третьего столбца в его содержимое. Оставшаяся ширина выделяется пропорционально между первым и вторым столбцами на основе числа перед звездой. В этом примере ширина второго столбца в два раза превышает ширину первого столбца (так как * идентична 1*).

Пространство между строками и столбцами

По умолчанию Grid строки разделяются на 6 единиц пространства, независимых от устройства. Grid Аналогичным образом столбцы разделяются 6 единицами пространства, независимыми от устройства. Эти значения по умолчанию можно изменить, задав RowSpacing значения и ColumnSpacing свойства соответственно:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridDemos.Views.GridSpacingPage"
             Title="Grid spacing demo">
    <Grid RowSpacing="0"
          ColumnSpacing="0">
        ..
    </Grid>
</ContentPage>

В этом примере создается интервал Grid между строками и столбцами:

Снимок экрана: Сетка без интервала между ячейками

Совет

ColumnSpacing Свойства RowSpacing можно задать для отрицательных значений, чтобы сделать содержимое ячейки перекрывающимся.

Эквивалентный код на C# выглядит так:

public GridSpacingPageCS()
{
    Grid grid = new Grid
    {
        RowSpacing = 0,
        ColumnSpacing = 0,
        // ...
    };
    // ...

    Content = grid;
}

Точное понимание

Дочерние представления в Grid ячейках могут размещаться по свойствам и VerticalOptions ячейкамHorizontalOptions. Эти свойства можно задать в следующих полях из LayoutOptions структуры:

Внимание

Поля AndExpands структуры LayoutOptions применимы только к StackLayout объектам.

Следующий XAML создает Grid с девятью равными размерами ячеек и помещает Label в каждую ячейку другую выравнивание:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GridDemos.Views.GridAlignmentPage"
             Title="Grid alignment demo">
    <Grid RowSpacing="0"
          ColumnSpacing="0">
        <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>

В этом примере Label объекты в каждой строке одинаково выровнены по вертикали, но используют разные горизонтальные выравнивания. Кроме того, это можно считать Label объектами в каждом столбце одинаково выровнены по горизонтали, но с использованием разных вертикальных выравниваний:

Снимок экрана: выравнивание ячеек в сетке

Эквивалентный код на C# выглядит так:

public class GridAlignmentPageCS : ContentPage
{
    public GridAlignmentPageCS()
    {
        Grid grid = new Grid
        {
            RowSpacing = 0,
            ColumnSpacing = 0,
            RowDefinitions =
            {
                new RowDefinition(),
                new RowDefinition(),
                new RowDefinition()
            },
            ColumnDefinitions =
            {
                new ColumnDefinition(),
                new ColumnDefinition(),
                new ColumnDefinition()
            }
        };

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

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

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

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

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

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

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

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

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

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

Вложенные объекты Сетки

Можно Grid использовать в качестве родительского макета, содержащего вложенные дочерние Grid объекты или другие дочерние макеты. При вложении объектов, Grid.Rowсвойств , Grid.RowSpanGrid.Columnи Grid.ColumnSpan вложенных свойств всегда ссылаются на положение представлений в родительском объектеGrid.Grid

В следующем XAML показан пример вложенных Grid объектов:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:converters="clr-namespace:GridDemos.Converters"
             x:Class="GridDemos.Views.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 />
            <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>

В этом примере корневой Grid макет содержит BoxView в первой строке и дочерний Grid элемент во второй строке. Дочерний Grid элемент содержит Slider объекты, которые управляют цветом BoxView, отображаемым элементом, и Label объекты, отображающие значение каждого Slider:

Снимок экрана: вложенные сетки

Внимание

Чем глубже вы вложены Grid объекты и другие макеты, тем больше вложенных макетов повлияет на производительность. Дополнительные сведения см. в разделе "Выбор правильного макета".

Эквивалентный код на C# выглядит так:

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

    public ColorSlidersGridPageCS()
    {
        // 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(),
                new RowDefinition()
            }
        };

        boxView = new BoxView { Color = Color.Black };
        rootGrid.Children.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.Children.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.Children.Add(redLabel);

        greenSlider = new Slider();
        greenSlider.ValueChanged += OnSliderValueChanged;
        Grid.SetRow(greenSlider, 2);
        childGrid.Children.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.Children.Add(greenLabel);

        blueSlider = new Slider();
        blueSlider.ValueChanged += OnSliderValueChanged;
        Grid.SetRow(blueSlider, 4);
        childGrid.Children.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.Children.Add(blueLabel);

        // Place the child Grid in the root Grid
        rootGrid.Children.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);
    }
}