Ориентации устройстваDevice Orientation

Загрузить образец загрузить примерDownload Sample Download the sample

Это важно учитывать, как приложение будет использоваться и как альбомной ориентации могут быть включены для повышения удобства работы пользователей.It is important to consider how your application will be used and how landscape orientation can be incorporated to improve the user experience. Отдельные макеты, которые могут быть спроектированы для размещения нескольких ориентаций экрана и лучше всего использовать доступное пространство.Individual layouts can be designed to accommodate multiple orientations and best use the available space. На уровне приложения можно отключать или включать поворота.At the application level, rotation can be disabled or enabled.

Управление ориентацииControlling Orientation

Если вы используете Xamarin.Forms, поддерживаемый метод управления ориентации устройства — использовать параметры для каждого отдельного проекта.When using Xamarin.Forms, the supported method of controlling device orientation is to use the settings for each individual project.

iOSiOS

В iOS, ориентации устройства настроена для приложений, использующих Info.plist файла.On iOS, device orientation is configured for applications using the Info.plist file. Этот файл будет содержать параметры ориентации для iPhone и iPod, а также параметры для iPad, если приложение включает его в качестве целевого объекта.This file will include orientation settings for iPhone & iPod, as well as settings for iPad if the app includes it as a target. Ниже приведены инструкции, относящиеся к интегрированной среды разработки.The following are instructions specific to your IDE. Используйте параметры интегрированной среды разработки в верхней части этого документа, чтобы выбрать, какие инструкции, вы бы хотели см. в разделе:Use the IDE options at the top of this document to select which instructions you'd like to see:

В Visual Studio откройте проект iOS и откройте Info.plist.In Visual Studio, open the iOS project and open Info.plist. Файл откроется в панель конфигурации, начиная с вкладкой сведения о развертывании iPhone:The file will open into a configuration panel, starting with the iPhone Deployment Info tab:

сведения о развертывании в Visual Studio iPhone

Чтобы настроить ориентацию iPad, выберите сведения о развертывании iPad вкладки в верхней левой части панели, затем выберите из доступных ориентация:To configure iPad orientation, select the iPad Deployment Info tab at the top left of the panel, then select from the available orientations:

Поддерживаемые ориентации устройства в Visual Studio

AndroidAndroid

Чтобы управлять ориентацией на Android, откройте MainActivity.cs и установите ориентацию, с помощью атрибута Декорирование MainActivity класса:To control the orientation on Android, open MainActivity.cs and set the orientation using the attribute decorating the MainActivity class:

namespace MyRotatingApp.Droid
{
    [Activity (Label = "MyRotatingApp.Droid", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, ScreenOrientation = ScreenOrientation.Landscape)] //This is what controls orientation
    public class MainActivity : FormsAppCompatActivity
    {
        protected override void OnCreate (Bundle bundle)
...

Xamarin.Android поддерживает несколько параметров для указания ориентации:Xamarin.Android supports several options for specifying orientation:

  • Альбомная – заставляет приложение ориентации на альбомную, независимо от того, данные датчиков.Landscape – forces the application orientation to be landscape, regardless of sensor data.
  • Книжная – заставляет приложение ориентации на книжной ориентации, независимо от того, данные датчиков.Portrait – forces the application orientation to be portrait, regardless of sensor data.
  • Пользователь – приводит к быть представлены с помощью пользователя предпочтительная ориентация приложения.User – causes the application to be presented using the user's preferred orientation.
  • За – приводит к ориентации приложения должен совпадать с ориентацию действия за ней.Behind – causes the application's orientation to be the same as the orientation of the activity behind it.
  • Датчик – вызывает ориентация приложения будет определяться датчика, в том случае, даже если пользователь отключил автоматического поворота.Sensor – causes the application's orientation to be determined by the sensor, even if the user has disabled automatic rotation.
  • SensorLandscape – предписывает приложению использовать альбомной ориентации, при использовании данных датчиков, чтобы изменить направление экрана направлена (благодаря чему экрана не будет считаться сверху вниз).SensorLandscape – causes the application to use landscape orientation while using sensor data to change the direction the screen is facing (so that the screen isn't seen as upside down).
  • SensorPortrait – предписывает приложению использовать книжной ориентации, при использовании данных датчиков, чтобы изменить направление экрана направлена (благодаря чему экрана не будет считаться сверху вниз).SensorPortrait – causes the application to use portrait orientation while using sensor data to change the direction the screen is facing (so that the screen isn't seen as upside down).
  • ReverseLandscape – предписывает приложению использовать альбомной ориентации, с которыми сталкиваются противоположном направлении от обычного, таким образом, чтобы отображаться «сверху вниз.»ReverseLandscape – causes the application to use landscape orientation, facing the opposite direction from usual, so as to appear "upside down."
  • ReversePortrait – предписывает приложению использовать книжной ориентации, с которыми сталкиваются противоположном направлении от обычного, таким образом, чтобы отображаться «сверху вниз.»ReversePortrait – causes the application to use portrait orientation, facing the opposite direction from usual, so as to appear "upside down."
  • FullSensor – заставляет приложение полагаться на данные датчиков, чтобы выбрать правильную ориентацию (из возможных 4).FullSensor – causes the application to rely on sensor data to select the correct orientation (out of the possible 4).
  • FullUser – предписывает приложению использовать параметры ориентации пользователя.FullUser – causes the application to use the user's orientation preferences. Если включен автоматический поворот, можно использовать все 4 ориентации.If automatic rotation is enabled, then all 4 orientations can be used.
  • UserLandscape[не поддерживается] предписывает приложению использовать альбомной ориентации, если у пользователя нет автоматического поворота включен, в этом случае он будет использовать датчик для определения ориентации.UserLandscape[Not Supported] causes the application to use landscape orientation, unless the user has automatic rotation enabled, in which case it will use the sensor to determine orientation. Этот параметр приведет к разрыву компиляции.This option will break compilation.
  • UserPortrait[не поддерживается] предписывает приложению использовать книжной ориентации, если у пользователя нет автоматического поворота включен, в этом случае будет использоваться датчик для определения ориентации.UserPortrait[Not Supported] causes the application to use portrait orientation, unless the user has automatic rotation enabled, in which case it will use the sensor to determine orientation. Этот параметр приведет к разрыву компиляции.This option will break compilation.
  • Блокировки[не поддерживается] предписывает приложению использовать ориентацию экрана, то при запуске без ответа на изменения в устройстве физический Ориентация.Locked[Not Supported] causes the application to use the screen orientation, whatever it is at launch, without responding to changes in the device's physical orientation. Этот параметр приведет к разрыву компиляции.This option will break compilation.

Обратите внимание, что собственных API Android предоставляют массу контроль над управление ориентации, включая параметры, которые явно указана другая пользователя выражен предпочтения.Note that the native Android APIs provide a lot of control over how orientation is managed, including options that explicitly contradict the user's expressed preferences.

Универсальная платформа WindowsUniversal Windows platform

В универсальной платформы Windows (UWP), поддерживаемые ориентации задаются в Package.appxmanifest файла.On the Universal Windows Platform (UWP), supported orientations are set in the Package.appxmanifest file. Открытия манифеста откроет панель конфигурации, где можно выбрать поддерживаемые ориентации.Opening the manifest will reveal a configuration panel where supported orientations can be selected.

Реагирование на изменения в ориентацииReacting to Changes in Orientation

Xamarin.Forms не предлагает все собственные события для уведомления приложения ориентации изменений в общем коде.Xamarin.Forms does not offer any native events for notifying your app of orientation changes in shared code. Тем не менее SizeChanged событие Page применяется, когда доля ширины или высоты Page изменения.However, the SizeChanged event of the Page fires when either the width or height of the Page changes. Если ширина Page больше, чем высота, устройство находится в альбомной ориентации.When the width of the Page is greater than the height, the device is in landscape mode. Дополнительные сведения см. в разделе отобразить изображение, в зависимости от ориентации экрана.For more information, see Display an Image based on Screen Orientation.

Примечание

Нет существующих, бесплатный пакет NuGet для получения уведомлений об изменениях ориентации в общем коде.There is an existing, free NuGet package for receiving notifications of orientation changes in shared code. См. в разделе репозиторий GitHub Дополнительные сведения.See the GitHub repo for more information.

Кроме того, можно переопределить OnSizeAllocated метод Page, вставка любой макет изменения логики существует.Alternatively, it's possible to override the OnSizeAllocated method on a Page, inserting any layout change logic there. OnSizeAllocated Метод вызывается всякий раз, когда Page выделяется новый размер, что происходит при повороте устройства.The OnSizeAllocated method is called whenever a Page is allocated a new size, which happens whenever the device is rotated. Обратите внимание, что базовая реализация OnSizeAllocated выполняет функции важные макета, поэтому очень важно вызвать базовую реализацию в переопределении:Note that the base implementation of OnSizeAllocated performs important layout functions, so it is important to call the base implementation in the override:

protected override void OnSizeAllocated(double width, double height)
{
    base.OnSizeAllocated(width, height); //must be called
}

Невозможность выполнения этот шаг приведет к сбою страницы.Failure to take that step will result in a non-functioning page.

Обратите внимание, что OnSizeAllocated метод может вызываться многократно при повороте устройства.Note that the OnSizeAllocated method may be called many times when a device is rotated. Изменение макета каждый раз слишком затратно ресурсов и может привести к мерцание.Changing your layout each time is wasteful of resources and can lead to flickering. Рассмотрите возможность использования переменной экземпляра на странице для отслеживания, является ли в альбомной или книжной ориентации и перерисовывать только при наличии изменений:Consider using an instance variable within your page to track whether the orientation is in landscape or portrait, and only redraw when there is a change:

private double width = 0;
private double height = 0;

protected override void OnSizeAllocated(double width, double height)
{
    base.OnSizeAllocated(width, height); //must be called
    if (this.width != width || this.height != height)
    {
        this.width = width;
        this.height = height;
        //reconfigure layout
    }
}

После обнаружения изменений в ориентации устройства, может потребоваться добавить или удалить дополнительные представления с пользовательского интерфейса реагировать на изменения в доступное пространство.Once a change in device orientation has been detected, you may want to add or remove additional views to/from your user interface to react to the change in available space. Например рассмотрим встроенные калькулятора на каждой платформе в книжной ориентации:For example, consider the built-in calculator on each platform in portrait:

и в альбомной ориентации.and landscape:

Обратите внимание на то, что приложениям использовать преимущества доступное пространство, добавив дополнительные функциональные возможности в альбомной ориентации.Notice that the apps take advantage of the available space by adding more functionality in landscape.

Гибкий макетResponsive Layout

Существует возможность разработки интерфейсов, с помощью встроенных макетов, таким образом, чтобы они корректно переход при повороте устройства.It is possible to design interfaces using the built-in layouts so that they transition gracefully when the device is rotated. Во время проектирования интерфейсов, которые будут продолжать привлекательными при изменении ориентации учитывайте следующие общие правила:When designing interfaces that will continue to be appealing when responding to changes in orientation consider the following general rules:

  • Обратите внимание на соотношение – изменения ориентации может вызвать проблемы, при некоторых предположений относительно коэффициенты.Pay attention to ratios – changes in orientation can cause problems when certain assumptions are made with regards to ratios. Например представление, которое будет иметь достаточно места в 1/3 расстояние по вертикали в книжной ориентации экрана может не поместиться в 1/3 по вертикали в альбомной ориентации.For example, a view that would have plenty of space in 1/3 of the vertical space of a screen in portrait may not fit into 1/3 of the vertical space in landscape.
  • Будьте внимательны с абсолютными значениями – абсолютные (области в пикселях) значения, которые имеют смысл в книжной ориентации не имеет смысла в альбомной ориентации.Be careful with absolute values – absolute (pixel) values that make sense in portrait may not make sense in landscape. При необходимости абсолютные значения использования вложенным макетам во избежание их влияния.When absolute values are necessary, use nested layouts to isolate their impact. Например, было бы разумным использовать абсолютные значения в TableView ItemTemplate при шаблона элемента имеет гарантированной универсальный высоту.For example, it would be reasonable to use absolute values in a TableView ItemTemplate when the item template has a guaranteed uniform height.

Выше правила также применяются в том случае, если реализация интерфейсов нескольких размеров экрана и являются обычно считается лучшим.The above rules also apply when implementing interfaces for multiple screen sizes and are generally considered best-practice. Остальная часть в этом руководстве объясняется, конкретные примеры быстрые макетов с помощью каждого из первичного макетов в Xamarin.Forms.The rest of this guide will explain specific examples of responsive layouts using each of the primary layouts in Xamarin.Forms.

Примечание

Для ясности в следующих разделах демонстрируются способы реализации быстро реагирующих макеты, используя лишь один из типов Layout за раз.For clarity, the following sections demonstrate how to implement responsive layouts using just one type of Layout at a time. На практике часто бывает проще смешивать Layouts для достижения нужного макета, с помощью простых и интуитивно Layout для каждого компонента.In practice, it is often simpler to mix Layouts to achieve a desired layout using the simpler or most intuitive Layout for each component.

StackLayoutStackLayout

Рассмотрим следующее приложение, отображается в книжной ориентации.Consider the following application, displayed in portrait:

и в альбомной ориентации.and landscape:

Выполняется с помощью следующих XAML:That is accomplished with the following XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResponsiveLayout.StackLayoutPageXaml"
Title="Stack Photo Editor - XAML">
    <ContentPage.Content>
        <StackLayout Spacing="10" Padding="5" Orientation="Vertical"
        x:Name="outerStack"> <!-- can change orientation to make responsive -->
            <ScrollView>
                <StackLayout Spacing="5" HorizontalOptions="FillAndExpand"
                    WidthRequest="1000">
                    <StackLayout Orientation="Horizontal">
                        <Label Text="Name: " WidthRequest="75"
                            HorizontalOptions="Start" />
                        <Entry Text="deer.jpg"
                            HorizontalOptions="FillAndExpand" />
                    </StackLayout>
                    <StackLayout Orientation="Horizontal">
                        <Label Text="Date: " WidthRequest="75"
                            HorizontalOptions="Start" />
                        <Entry Text="07/05/2015"
                            HorizontalOptions="FillAndExpand" />
                    </StackLayout>
                    <StackLayout Orientation="Horizontal">
                        <Label Text="Tags:" WidthRequest="75"
                            HorizontalOptions="Start" />
                        <Entry Text="deer, tiger"
                            HorizontalOptions="FillAndExpand" />
                    </StackLayout>
                    <StackLayout Orientation="Horizontal">
                        <Button Text="Save" HorizontalOptions="FillAndExpand" />
                    </StackLayout>
                </StackLayout>
            </ScrollView>
            <Image  Source="deer.jpg" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

C# используется для изменения ориентации outerStack зависимости от ориентации устройства:Some C# is used to change the orientation of outerStack based on the orientation of the device:

protected override void OnSizeAllocated (double width, double height){
    base.OnSizeAllocated (width, height);
    if (width != this.width || height != this.height) {
        this.width = width;
        this.height = height;
        if (width > height) {
            outerStack.Orientation = StackOrientation.Horizontal;
        } else {
            outerStack.Orientation = StackOrientation.Vertical;
        }
    }
}

Обратите внимание на следующее условия:Note the following:

  • outerStack настраивается для представления изображений и элементов управления в виде горизонтальной или вертикальной стека в зависимости от ориентации, чтобы лучше всего воспользоваться преимуществами доступное пространство.outerStack is adjusted to present the image and controls as a horizontal or vertical stack depending on orientation, to best take advantage of the available space.

AbsoluteLayoutAbsoluteLayout

Рассмотрим следующее приложение, отображается в книжной ориентации.Consider the following application, displayed in portrait:

и в альбомной ориентации.and landscape:

Выполняется с помощью следующих XAML:That is accomplished with the following XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResponsiveLayout.AbsoluteLayoutPageXaml"
Title="AbsoluteLayout - XAML" BackgroundImageSource="deer.jpg">
    <ContentPage.Content>
        <AbsoluteLayout>
            <ScrollView AbsoluteLayout.LayoutBounds="0,0,1,1"
                AbsoluteLayout.LayoutFlags="PositionProportional,SizeProportional">
                <AbsoluteLayout>
                    <Image Source="deer.jpg"
                        AbsoluteLayout.LayoutBounds=".5,0,300,300"
                        AbsoluteLayout.LayoutFlags="PositionProportional" />
                    <BoxView Color="#CC1A7019" AbsoluteLayout.LayoutBounds=".5
                        300,.7,50" AbsoluteLayout.LayoutFlags="XProportional
                        WidthProportional" />
                    <Label Text="deer.jpg" AbsoluteLayout.LayoutBounds = ".5
                        310,1, 50" AbsoluteLayout.LayoutFlags="XProportional
                        WidthProportional" HorizontalTextAlignment="Center" TextColor="White" />
                </AbsoluteLayout>
            </ScrollView>
            <Button Text="Previous" AbsoluteLayout.LayoutBounds="0,1,.5,60"
                AbsoluteLayout.LayoutFlags="PositionProportional
                    WidthProportional"
                BackgroundColor="White" TextColor="Green" BorderRadius="0" />
            <Button Text="Next" AbsoluteLayout.LayoutBounds="1,1,.5,60"
                AbsoluteLayout.LayoutFlags="PositionProportional
                    WidthProportional" BackgroundColor="White"
                    TextColor="Green" BorderRadius="0" />
        </AbsoluteLayout>
    </ContentPage.Content>
</ContentPage>

Обратите внимание на следующее условия:Note the following:

  • Из-за того, в который странице макетирования нет необходимости для процедурного кода представить скорость реагирования.Because of the way the page has been laid out, there is no need for procedural code to introduce responsiveness.
  • ScrollView , Используется для разрешить метки отображаться, даже если высота экрана не меньше, чем сумма предопределенной высоту кнопки и изображения.The ScrollView is being used to allow the label to be visible even when the height of the screen is less than the sum of the fixed heights of the buttons and the image.

RelativeLayoutRelativeLayout

Рассмотрим следующее приложение, отображается в книжной ориентации.Consider the following application, displayed in portrait:

и в альбомной ориентации.and landscape:

Выполняется с помощью следующих XAML:That is accomplished with the following XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResponsiveLayout.RelativeLayoutPageXaml"
Title="RelativeLayout - XAML"
BackgroundImageSource="deer.jpg">
    <ContentPage.Content>
        <RelativeLayout x:Name="outerLayout">
            <BoxView BackgroundColor="#AA1A7019"
                RelativeLayout.WidthConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=1}"
                RelativeLayout.HeightConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Height,Factor=1}"
                RelativeLayout.XConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=0,Constant=0}"
                RelativeLayout.YConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Height,Factor=0,Constant=0}" />
            <ScrollView
                RelativeLayout.WidthConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=1}"
                RelativeLayout.HeightConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Height,Factor=1,Constant=-60}"
                RelativeLayout.XConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=0,Constant=0}"
                RelativeLayout.YConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Height,Factor=0,Constant=0}">
                <RelativeLayout>
                    <Image Source="deer.jpg" x:Name="imageDeer"
                        RelativeLayout.WidthConstraint="{ConstraintExpression
                            Type=RelativeToParent,Property=Width,Factor=.8}"
                        RelativeLayout.XConstraint="{ConstraintExpression
                            Type=RelativeToParent,Property=Width,Factor=.1}"
                        RelativeLayout.YConstraint="{ConstraintExpression
                            Type=RelativeToParent,Property=Height,Factor=0,Constant=10}" />
                    <Label Text="deer.jpg" HorizontalTextAlignment="Center"
                        RelativeLayout.WidthConstraint="{ConstraintExpression
                            Type=RelativeToParent,Property=Width,Factor=1}"
                        RelativeLayout.HeightConstraint="{ConstraintExpression
                            Type=RelativeToParent,Property=Height,Factor=0,Constant=75}"
                        RelativeLayout.XConstraint="{ConstraintExpression
                            Type=RelativeToParent,Property=Width,Factor=0,Constant=0}"
                        RelativeLayout.YConstraint="{ConstraintExpression
                            Type=RelativeToView,ElementName=imageDeer,Property=Height,Factor=1,Constant=20}" />
                </RelativeLayout>

            </ScrollView>

            <Button Text="Previous" BackgroundColor="White" TextColor="Green" BorderRadius="0"
                RelativeLayout.YConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Height,Factor=1,Constant=-60}"
                RelativeLayout.XConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=0,Constant=0}"
                RelativeLayout.HeightConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=0,Constant=60}"
                RelativeLayout.WidthConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=.5}"
                 />
            <Button Text="Next" BackgroundColor="White" TextColor="Green" BorderRadius="0"
                RelativeLayout.XConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=.5}"
                RelativeLayout.YConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Height,Factor=1,Constant=-60}"
                RelativeLayout.HeightConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=0,Constant=60}"
                RelativeLayout.WidthConstraint="{ConstraintExpression
                    Type=RelativeToParent,Property=Width,Factor=.5}"
                />
        </RelativeLayout>
    </ContentPage.Content>
</ContentPage>

Обратите внимание на следующее условия:Note the following:

  • Из-за того, в который странице макетирования нет необходимости для процедурного кода представить скорость реагирования.Because of the way the page has been laid out, there is no need for procedural code to introduce responsiveness.
  • ScrollView , Используется для разрешить метки отображаться, даже если высота экрана не меньше, чем сумма предопределенной высоту кнопки и изображения.The ScrollView is being used to allow the label to be visible even when the height of the screen is less than the sum of the fixed heights of the buttons and the image.

GridGrid

Рассмотрим следующее приложение, отображается в книжной ориентации.Consider the following application, displayed in portrait:

и в альбомной ориентации.and landscape:

Выполняется с помощью следующих XAML:That is accomplished with the following XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResponsiveLayout.GridPageXaml"
Title="Grid - XAML">
    <ContentPage.Content>
        <Grid x:Name="outerGrid">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="60" />
            </Grid.RowDefinitions>
            <Grid x:Name="innerGrid" Grid.Row="0" Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Image Source="deer.jpg" Grid.Row="0" Grid.Column="0" HeightRequest="300" WidthRequest="300" />
                <Grid x:Name="controlsGrid" Grid.Row="0" Grid.Column="1" >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Label Text="Name:" Grid.Row="0" Grid.Column="0" />
                    <Label Text="Date:" Grid.Row="1" Grid.Column="0" />
                    <Label Text="Tags:" Grid.Row="2" Grid.Column="0" />
                    <Entry Grid.Row="0" Grid.Column="1" />
                    <Entry Grid.Row="1" Grid.Column="1" />
                    <Entry Grid.Row="2" Grid.Column="1" />
                </Grid>
            </Grid>
            <Grid x:Name="buttonsGrid" Grid.Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Button Text="Previous" Grid.Column="0" />
                <Button Text="Save" Grid.Column="1" />
                <Button Text="Next" Grid.Column="2" />
            </Grid>
        </Grid>
    </ContentPage.Content>
</ContentPage>

А также следующие процедурный код для обработки изменений поворота:Along with the following procedural code to handle rotation changes:

private double width;
private double height;

protected override void OnSizeAllocated (double width, double height){
    base.OnSizeAllocated (width, height);
    if (width != this.width || height != this.height) {
        this.width = width;
        this.height = height;
        if (width > height) {
            innerGrid.RowDefinitions.Clear();
            innerGrid.ColumnDefinitions.Clear ();
            innerGrid.RowDefinitions.Add (new RowDefinition{ Height = new GridLength (1, GridUnitType.Star) });
            innerGrid.ColumnDefinitions.Add (new ColumnDefinition { Width = new GridLength (1, GridUnitType.Star) });
            innerGrid.ColumnDefinitions.Add (new ColumnDefinition { Width = new GridLength (1, GridUnitType.Star) });
            innerGrid.Children.Remove (controlsGrid);
            innerGrid.Children.Add (controlsGrid, 1, 0);
        } else {
            innerGrid.RowDefinitions.Clear();
            innerGrid.ColumnDefinitions.Clear ();
            innerGrid.ColumnDefinitions.Add (new ColumnDefinition{ Width = new GridLength (1, GridUnitType.Star) });
            innerGrid.RowDefinitions.Add (new RowDefinition { Height = new GridLength (1, GridUnitType.Auto) });
            innerGrid.RowDefinitions.Add (new RowDefinition { Height = new GridLength (1, GridUnitType.Star) });
            innerGrid.Children.Remove (controlsGrid);
            innerGrid.Children.Add (controlsGrid, 0, 1);
        }
    }
}

Обратите внимание на следующее условия:Note the following:

  • Из-за того, в который макетирования страницы имеется метод для изменения положения элементов управления сетки.Because of the way the page has been laid out, there is a method to change the grid placement of the controls.