Organización de vistas con Grid
Imagine que va a crear una página en la que se muestran imágenes en una cuadrícula de 7 x 5. Esta página se puede crear con varios contenedores de StackLayout
horizontales y verticales. Pero resultaría tedioso de programar y podría provocar problemas de rendimiento debido a los requisitos de memoria y procesamiento de los distintos paneles de diseño. El panel de diseño Grid
es una opción mejor para las interfaces de usuario que necesitan filas y columnas. En esta unidad, aprenderá a definir un diseño Grid
y ubicar vistas dentro de sus celdas.
¿Qué es Grid?
Grid
es un panel de diseño que consta de filas y columnas. En la ilustración siguiente se muestra una vista conceptual de una cuadrícula.
Las vistas se colocan en las celdas que se crean a partir de la intersección de las filas y las columnas. Por ejemplo, si crea un diseño Grid
que tiene tres columnas y dos filas, habrá seis celdas disponibles para las vistas. Las filas y las columnas pueden tener diferentes tamaños, o bien se pueden establecer para que se adapten de forma automática al tamaño de los elementos secundarios que se colocan en su interior. Las vistas secundarias pueden ocupar una sola celda o varias. Esta flexibilidad hace que Grid
sea una buena elección como panel de diseño raíz para muchas aplicaciones.
Cómo especificar las filas y columnas de una cuadrícula
Al crear un Grid
, puede definir cada fila y columna individualmente. Este sistema proporciona control total sobre el alto de cada fila y el ancho de cada columna. Todos los diseños Grid
tienen una colección de objetos RowDefinition
y ColumnDefinition
que definen la forma de la cuadrícula. Debe rellenar esas colecciones con instancias de RowDefinition
y ColumnDefinition
, cada una para representar una fila o columna de la interfaz de usuario.
Estos son dos fragmentos de código en los que se muestran las definiciones de clase para RowDefinition
y ColumnDefinition
:
public sealed class RowDefinition : ...
{
...
public GridLength Height { get; set; }
}
public sealed class ColumnDefinition : ...
{
...
public GridLength Width { get; set; }
}
Observe que RowDefinition
tiene una propiedad denominada Height
y que ColumnDefinition
tiene una propiedad denominada Width
. Use estas propiedades para establecer el alto de una fila y el ancho de una columna, como se describe en las secciones siguientes.
¿Qué es GridLength?
El tipo de datos de las propiedades Width
y Height
es GridLength
. Este tipo contiene dos propiedades: GridUnitType
y Value
. Este es un fragmento de código en el que se muestra una parte de la definición del tipo.
public struct GridLength
{
...
public GridUnitType GridUnitType { get; }
public double Value { get; }
}
Puede establecer la propiedad GridUnitType
en uno de estos valores:
Absolute
Auto
Star
Cada uno de estos valores se examinará con más detalle.
Absolute GridUnitType
Absolute
especifica que la fila o la columna tienen un tamaño fijo. Puede usar la propiedad Value
para indicar el tamaño. Este es un ejemplo en el que se muestra cómo establecer el alto de una fila en un tamaño fijo de 100
unidades de dispositivo en C#. Observe cómo se podría usar el constructor de GridLength
, que toma un valor numérico. Este constructor establece GridUnitType
en Absolute
de forma automática.
var row = new RowDefinition() { Height = new GridLength(100) };
En el lenguaje XAML, solo tiene que proporcionar un valor numérico. El analizador XAML invoca un convertidor de tipos para crear la instancia de GridLength
. En este ejemplo se muestra lo mismo en XAML:
<RowDefinition Height="100" />
Auto GridUnitType
Auto
cambia automáticamente el tamaño de la fila o la columna para ajustarlo a las vistas secundarias. Grid
examina todas las vistas secundarias de esa fila o columna, selecciona la de mayor tamaño y, después, hace que la fila o la columna sea lo suficientemente grande para ajustarse a ese elemento secundario. Cuando se crea una definición de fila en el código, se omite el valor numérico. Se puede usar cualquier valor. En este ejemplo se muestra cómo se establecería el alto de una fila con ajuste de tamaño automático en C#. Observe que se ha elegido arbitrariamente 1
para el valor.
var row = new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) };
En XAML, se usa el valor Auto
. En este ejemplo se muestra lo mismo en XAML.
<RowDefinition Height="Auto" />
Star GridUnitType
Star
ofrece un ajuste de tamaño proporcional. En el dimensionamiento proporcional, el tamaño se determina por el espacio total disponible y la relación que solicita cada fila o columna. En lenguaje coloquial, esto se suele denominar variación de tamaño proporcional en lugar de dimensionamiento proporcional.
Se analizará el proceso del uso de la variación de tamaño proporcional para las filas de una cuadrícula.
Determine el espacio disponible:
Grid
examina todas las filas en las queGrid
se usa la variación de tamaño proporcional. Suma el alto de todas esas filas y resta ese total del alto del propio diseñoGrid
. Este cálculo proporciona la cantidad de espacio disponible para todas las filas con variación de tamaño proporcional.Divida el espacio disponible: Después,
Grid
divide el espacio disponible entre todas las filas con variación de tamaño proporcional según el valorValue
de cada fila. La propiedadValue
se puede considerar un multiplicador que determina la proporción entre todas las filas definidas con variación de tamaño proporcional. Por ejemplo, si tuviera dos filas con variación de tamaño proporcional, las dos con1
como multiplicador, el espacio disponible se dividiría de forma equitativa entre las dos. Pero si una de ellas tuviera2
como el valor, obtendría el doble de espacio que la otra.
En este ejemplo se muestra cómo se establecería el alto de una fila para ser 2 Star
en C#:
var row = new RowDefinition() { Height = new GridLength(2, GridUnitType.Star) };
En XAML, para representar la variación de tamaño proporcional se usa el símbolo *
. El valor y el signo *
se combinan en una sola cadena y un convertidor de tipos crea GridLength
de forma automática. Este es el mismo ejemplo en XAML.
<RowDefinition Height="2*" />
Colecciones de cuadrícula
Después de definir las filas y columnas mediante RowDefinition
y ColumnDefinition
, puede agregarlas a un Grid
. Use las propiedades RowDefinitions
y ColumnDefinitions
de colección de la Grid
. Rellenar estas colecciones se realiza habitualmente en XAML.
En este ejemplo se muestra cómo definir cuatro filas y agregarlas a un diseño Grid
mediante la propiedad RowDefinitions
:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
...
</Grid>
Esta definición se puede acortar a:
<Grid RowDefinitions="100, Auto, 1*, 2*">
...
</Grid>
El XAML para definir columnas es análogo al XAML anterior. Excepto que usaría ColumnDefinitions
y establecería Width
.
En tiempo de ejecución, este código XAML generará un diseño Grid
con cuatro filas. La primera fila tiene una altura fija de 100
unidades de dispositivo. La segunda fila tiene la altura de la vista más alta de la fila. En la tercera y cuarta filas se usa la variación de tamaño proporcional, lo que significa que toman el espacio disponible restante y lo dividen proporcionalmente en función de su multiplicador Value
. Como la tercera fila es 1*
y la cuarta es 2*
, la cuarta duplica la altura de la tercera.
Tamaño predeterminado de filas y columnas
El valor predeterminado para las filas y columnas es el tamaño 1*
. Por ejemplo, vea el siguiente código XAML.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
...
</Grid>
Esta definición se puede acortar a:
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
...
</Grid>
Como en ninguna de las filas o columnas se ha especificado un tamaño, se aplica 1*
a todas ellas. En el entorno de ejecución, esta configuración crea un diseño Grid
uniforme, lo que significa que todas las filas tienen el mismo alto y todas las columnas el mismo ancho.
Cómo agregar vistas a una cuadrícula
Cuando se agrega una vista a un Grid
, se agrega a una celda concreta. Las celdas se crean en las posiciones de intersección de las filas y columnas. Para colocar una vista en una celda, es necesario conocer la ubicación de la celda. Para identificar una celda se usa una combinación de un número de fila y un número de columna.
Numeración de filas y columnas
La numeración de filas y columnas comienza en cero. El origen es la esquina superior izquierda. En esta ilustración se muestra la numeración de un diseño Grid
con cuatro filas y dos columnas.
Por ejemplo, si quisiera agregar una vista a la celda inferior derecha, diría que la posición de la vista es row 3 column 1
.
Adición de una vista a una cuadrícula mediante propiedades adjuntas
Se necesita una manera de especificar el número de columna y de fila de una vista cuando se agrega a una cuadrícula. Una solución sería definir las propiedades Row
y Column
en la clase base View
para poder especificar la posición directamente en la vista. Esta técnica podría funcionar, pero no es el enfoque más eficaz. Las vistas no son siempre van a estar en un diseño Grid
, por lo que en ocasiones esas propiedades no serán necesarias. Un mejor enfoque consiste en usar propiedades adjuntas.
Una propiedad adjunta es la que se define en una clase, pero se establece en objetos de otros tipos.
Imagine que las propiedades adjuntas son como una colección de pares clave-valor que forman parte de una vista. Cuando agrega una vista a una Grid
, especifica la fila y la columna. Mediante las propiedades adjuntas, se puede agregar un par clave-valor con la clave Grid.Row
, y un valor que indica el número de la fila. Cuando el diseño Grid
está listo para colocar la vista, comprueba la colección para ver si hay una clave denominada Grid.Row
. Si existe, Grid
usa el valor para colocar la vista.
En este ejemplo se muestra cómo crear un diseño Grid
y agregar una vista mediante propiedades adjuntas:
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
<BoxView Grid.Row="1" Grid.Column="0" Color="Navy" />
</Grid>
Como puede ver, Grid.Row=1
y Grid.Column=0
son pares clave-valor que se agregan a una colección interna del BoxView
. Grid
usa esos valores para determinar dónde se debe colocar la vista. Este diseño Grid
tendría el aspecto siguiente si la aplicación se ejecutara en un dispositivo.
Cómo hacer que una vista abarque varias filas o columnas
Hay dos propiedades adjuntas más que debe tener en cuenta: Grid.RowSpan
y Grid.ColumnSpan
. Estas propiedades especifican cuántas filas o columnas debe ocupar la vista. Por ejemplo, vea el siguiente código XAML.
<Grid RowDefinitions="*, *, *" ColumnDefinitions="*, *">
<BoxView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Color="Navy" />
</Grid>
Observe que este ejemplo establece el valor ColumnSpan
en 2
. Esta vista ocupará dos columnas a partir de Column 0
. Este diseño Grid
tendría el aspecto siguiente si la aplicación se ejecutara en un dispositivo.