Diseños

.NET MAUI layout classes.

Las clases de diseño de .NET Multi-platform App UI (.NET MAUI) permiten organizar y agrupar controles de interfaz de usuario en la aplicación. Elegir una clase de diseño requiere saber cómo coloca el diseño sus elementos secundarios y cómo dicho diseño ajusta el tamaño de sus elementos secundarios. Además, puede ser necesario anidar diseños para crear el diseño deseado.

StackLayout

StackLayout organiza los elementos en una pila unidimensional, ya sea horizontal o verticalmente. La propiedad Orientation especifica la dirección de los elementos y la orientación predeterminada es Vertical. StackLayout suele usarse para organizar una pequeña subsección de la interfaz de usuario en una página.

En el código XAML siguiente se muestra cómo crear un objeto StackLayout vertical que contenga tres objetos Label:

<StackLayout Margin="20,35,20,25">
    <Label Text="The StackLayout has its Margin property set, to control the rendering position of the StackLayout." />
    <Label Text="The Padding property can be set to specify the distance between the StackLayout and its children." />
    <Label Text="The Spacing property can be set to specify the distance between views in the StackLayout." />
</StackLayout>

En StackLayout, si el tamaño de un elemento no se establece explícitamente, se expande para rellenar el ancho disponible, o el alto si la propiedad Orientation está establecida en Horizontal.

StackLayout a menudo se usa como diseño primario, que contiene otros diseños secundarios. Sin embargo, StackLayout no se debe usar para reproducir un diseño Grid mediante una combinación de objetos StackLayout. En el código siguiente se muestra un ejemplo de esta práctica incorrecta:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Details.HomePage"
             Padding="0,20,0,0">
    <StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Name:" />
            <Entry Placeholder="Enter your name" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Age:" />
            <Entry Placeholder="Enter your age" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Occupation:" />
            <Entry Placeholder="Enter your occupation" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Address:" />
            <Entry Placeholder="Enter your address" />
        </StackLayout>
    </StackLayout>
</ContentPage>

Es una pérdida de tiempo porque se realizan cálculos de diseño innecesarios. En su lugar, el diseño deseado se puede lograr mejor mediante Grid.

Para obtener más información sobre, consulta StackLayout.

HorizontalStackLayout

HorizontalStackLayout organiza las vistas secundarias en una pila horizontal unidimensional y es una alternativa más eficaz a StackLayout. HorizontalStackLayout suele usarse para organizar una subsección de la interfaz de usuario en una página.

En el código XAML siguiente se muestra cómo crear HorizontalStackLayout que contenga diferentes vistas secundarias:

<HorizontalStackLayout Margin="20">
   <Rectangle Fill="Red"
              HeightRequest="30"
              WidthRequest="30" />
   <Label Text="Red"
          FontSize="18" />
</HorizontalStackLayout>

En HorizontalStackLayout, si el tamaño de un elemento no se establece explícitamente, se expande para rellenar el alto disponible.

Para obtener más información, consulta HorizontalStackLayout.

VerticalStackLayout

VerticalStackLayout organiza las vistas secundarias en una pila vertical unidimensional y es una alternativa más eficaz para StackLayout. VerticalStackLayout suele usarse para organizar una subsección de la interfaz de usuario en una página.

En el código XAML siguiente se muestra cómo crear VerticalStackLayout que contenga tres objetos Label:

<VerticalStackLayout Margin="20,35,20,25">
    <Label Text="The VericalStackLayout has its Margin property set, to control the rendering position of the VerticalStackLayout." />
    <Label Text="The Padding property can be set to specify the distance between the VerticalStackLayout and its children." />
    <Label Text="The Spacing property can be set to specify the distance between views in the VerticalStackLayout." />
</VerticalStackLayout>

En VerticalStackLayout, si el tamaño de un elemento no se establece explícitamente, se expande para rellenar el ancho disponible.

Para obtener más información, consulte VerticalStackLayout.

Grid

Grid se usa para mostrar elementos en filas y columnas, que pueden tener tamaños proporcionales o absolutos. Las filas y columnas de una cuadrícula se especifican con las propiedades RowDefinitions y ColumnDefinitions.

Para colocar elementos en celdas Grid específicas, usa las propiedades adjuntas Grid.Column y Grid.Row. Para que los elementos abarquen varias filas y columnas, usa las propiedades adjuntas Grid.RowSpan y Grid.ColumnSpan.

Nota:

Un diseño Grid no debe confundirse con las tablas y no está pensado para presentar datos tabulares.

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

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>    
    <Label Text="Column 0, Row 0"
           WidthRequest="200" />
    <Label Grid.Column="1"
           Text="Column 1, Row 0" />
    <Label Grid.Row="1"
           Text="Column 0, Row 1" />
    <Label Grid.Column="1"
           Grid.Row="1"
           Text="Column 1, Row 1" />
</Grid>

En este ejemplo, el ajuste de tamaño funciona de la siguiente manera:

  • Cada fila tiene un alto explícito de 50 unidades independientes del dispositivo.
  • El ancho de la primera columna se establece en Auto y, por tanto, es tan ancho como sea necesario para sus elementos secundarios. En este caso, es de 200 unidades independientes del dispositivo de ancho para acomodar el ancho del primer Label.

El espacio se puede distribuir dentro de una columna o fila mediante el ajuste de tamaño automático, lo que permite que el tamaño de las columnas y de las filas se ajusten a su contenido. Esto se logra estableciendo el alto de RowDefinition o el ancho de ColumnDefinition en Auto. El ajuste de tamaño proporcional también se puede usar para distribuir el espacio disponible entre las filas y columnas de la cuadrícula en proporciones ponderadas. Esto se logra estableciendo el alto de RowDefinition o el ancho de ColumnDefinition en un valor que usa el operador *.

Precaución

Intenta asegurarte de establecer en tamaño Auto el menor número posible de filas y columnas. 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.

Para más información, consulta Cuadrícula.

FlexLayout

FlexLayout es similar a un elemento StackLayout en el sentido que muestra elementos secundarios horizontal o verticalmente en una pila. Sin embargo, un elemento FlexLayout también puede encapsular sus elementos secundarios si hay demasiados para caber en una sola fila o columna, y también permite un control más granular del tamaño, la orientación y la alineación de sus elementos secundarios.

En el código XAML siguiente se muestra cómo crear un objeto FlexLayout que muestra sus vistas en una sola columna:

<FlexLayout Direction="Column"
            AlignItems="Center"
            JustifyContent="SpaceEvenly">
    <Label Text="FlexLayout in Action" />
    <Button Text="Button" />
    <Label Text="Another Label" />
</FlexLayout>

En este ejemplo, el diseño funciona de la siguiente manera:

  • La propiedad Direction se establece en Column, lo que hace que los elementos secundarios del objeto FlexLayout se organicen en una sola columna de elementos.
  • La propiedad AlignItems se establece en Center, lo que hace que cada elemento se centre horizontalmente.
  • La propiedad JustifyContent se establece en SpaceEvenly, que asigna todo el espacio vertical restante de forma equitativa entre todos los elementos, y por encima del primer elemento, y por debajo del último elemento.

Para más información, consulta FlexLayout.

AbsoluteLayout

AbsoluteLayout se usa para colocar y ajustar el tamaño de los elementos mediante valores explícitos o valores relativos al tamaño del diseño. La posición se especifica en la esquina superior izquierda del elemento secundario en relación con la esquina superior izquierda de AbsoluteLayout.

AbsoluteLayout debe considerarse como un sistema de diseño de ámbito especial que solo se usará cuando el programador pueda aplicar un tamaño en los elementos secundarios o cuando el tamaño del elemento no afecte a la posición de otros elementos secundarios. Un uso estándar de este diseño es crear una superposición, que cubre la página con otros controles, quizás para impedir que el usuario interactúe con los controles normales de la página.

Importante

Las propiedades HorizontalOptions y VerticalOptions no tienen ningún efecto en los elementos secundarios de un AbsoluteLayout.

Dentro de AbsoluteLayout la propiedad adjunta AbsoluteLayout.LayoutBounds se usa para especificar la posición horizontal, posición vertical, anchura y altura de un elemento. Además, la propiedad adjunta AbsoluteLayout.LayoutFlags especifica cómo se interpretarán los límites del diseño.

En el código XAML siguiente se muestra cómo organizar elementos en AbsoluteLayout:

<AbsoluteLayout Margin="40">
    <BoxView Color="Red"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100"
             Rotation="30" />
    <BoxView Color="Green"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100"
             Rotation="60" />
    <BoxView Color="Blue"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100" />
</AbsoluteLayout>

En este ejemplo, el diseño funciona de la siguiente manera:

  • A cada BoxView se le asigna un tamaño explícito de 100x100 y se muestra en la misma posición, centrado horizontalmente.
  • El elemento BoxView rojo gira 30 grados y el elemento BoxView verde gira 60 grados.
  • En cada BoxView, la propiedad adjunta AbsoluteLayout.LayoutFlags se establece PositionProportional, lo que indica que la posición es proporcional al espacio restante después de que se tenga en cuenta la anchura y altura.

Precaución

Evita usar la propiedad AbsoluteLayout.AutoSize siempre que sea posible, ya que esto hará que el motor de diseño realice cálculos de diseño adicionales.

Para más información, consulta AbsoluteLayout.

BindableLayout

BindableLayout habilita cualquier clase de diseño que derive de la clase Layout para generar su contenido enlazando una colección de elementos, con la opción de establecer la apariencia de cada elemento con DataTemplate.

Un diseño enlazable se rellena con datos estableciendo su propiedad ItemsSource en cualquier colección que implemente IEnumerable y adjuntándole una clase derivada de Layout. La apariencia de cada elemento del diseño enlazable se puede definir estableciendo la propiedad BindableLayout.ItemTemplate adjunta en un elemento DataTemplate.

En el código XAML siguiente se muestra cómo enlazar StackLayout a una colección de elementos y definir su apariencia con DataTemplate:

<StackLayout BindableLayout.ItemsSource="{Binding User.TopFollowers}"
             Orientation="Horizontal">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding}"
                   Aspect="AspectFill"
                   WidthRequest="44"
                   HeightRequest="44" />
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

Los diseños enlazables solo deben usarse cuando la colección de elementos que se va a mostrar es pequeña y no es necesario desplazarse ni seleccionar.

Para más información, consulta BindableLayout.

Diseños personalizados

En .NET MAUI, las clases de diseño derivan de la clase abstracta Layout . Esta clase delega el diseño y la medida multiplataforma a una clase de administrador de diseño. Cada clase de administrador de diseño implementa la ILayoutManager interfaz , que especifica que Measure se deben proporcionar las implementaciones y ArrangeChildren :

  • La Measure implementación llama IView.Measure a en cada vista del diseño y devuelve el tamaño total del diseño según las restricciones.
  • La ArrangeChildren implementación determina dónde se debe colocar cada vista dentro de los límites del diseño y llama a Arrange en cada vista con sus límites adecuados. El valor devuelto es el tamaño real del diseño.

Los diseños de .NET MAUI tienen administradores de diseño predefinidos para controlar su diseño. Sin embargo, a veces es necesario organizar el contenido de la página mediante un diseño que no proporciona .NET MAUI. Esto se puede lograr escribiendo su propio diseño personalizado. Para obtener más información, consulte Diseños personalizados.

Transparencia de la entrada

Cada elemento visual tiene una propiedad enlazable InputTransparent que se usa para definir si el elemento puede recibir entrada. Su valor predeterminado es false, asegurándose de que el elemento puede recibir la entrada. Cuando esta propiedad está en un elemento true, el elemento no recibirá ninguna entrada. En su lugar, la entrada se pasará a cualquier elemento que esté visualmente detrás del elemento.

La clase Layout, de la que derivan todos los diseños, tiene una propiedad enlazable CascadeInputTransparent que controla si los elementos secundarios heredan la transparencia de entrada del diseño. Su valor predeterminado es true, asegurándose de que si se establece la propiedad InputTransparent en true todos los elementos del diseño no recibirán ninguna entrada.