Compartir a través de


Sistema de diseño

Actualización: noviembre 2007

En este tema se describe el sistema de diseño de Windows Presentation Foundation (WPF). Entender cómo y cuándo se producen los cálculos de diseño es esencial para crear interfaces de usuario de alto rendimiento con un aspecto profesional.

Este tema contiene las secciones siguientes.

  • Sistema de diseño

  • Rectángulos de selección de elementos

  • Medir y organizar elementos secundarios

  • Elementos de panel y comportamientos de diseño personalizado

  • Consideraciones sobre el rendimiento del diseño

  • Pasos adicionales

  • Temas relacionados

Sistema de diseño

El término "diseño" describe el proceso de medir y organizar los integrantes de la colección Children de un elemento Panel y, a continuación, dibujarlos en la pantalla. Se trata de un proceso intensivo y, cuanto mayor es la colección Children, mayor es el número de cálculos realizados. También se puede incluir mayor complejidad según el comportamiento de diseño definido por el elemento Panel que posee la colección. Un diseño relativamente sencillo, como Canvas, puede producir un rendimiento excelente si no se requiere un Panel más complejo, como Grid.

Cada vez que un UIElement secundario cambia su posición, tiene el potencial de desencadenar un nuevo paso del sistema de diseño. Como a tal, es importante entender los eventos que pueden invocar el sistema del diseño, puesto que la invocación innecesaria puede deteriorar el rendimiento de la aplicación.

En su versión más simple, el diseño es un sistema recursivo que conduce a la configuración del tamaño, posición y representación de un elemento en la pantalla. El sistema de diseño completa dos pasos por cada miembro de la colección Children: un paso de medida y un paso de organización. Cada Panel secundario proporciona sus propios métodos MeasureOverride y ArrangeOverride para lograr su propio comportamiento de diseño concreto. Se trata de la serie de eventos que se producen cada vez que se invoca el sistema de diseño.

  1. Un UIElement secundario comienza el proceso de diseño midiendo, en primer lugar, propiedades básicas.

  2. Se evalúan las propiedades de tamaño definidas en FrameworkElement, como Width, Height y Margin.

  3. Se aplica la lógica concreta de Panel, como la dirección de Dock o la Orientation de apilado.

  4. El contenido se organiza después de medir todos los elementos secundarios.

  5. Se dibuja la colección Children en la pantalla.

  6. Se invoca el proceso de nuevo si se agregan Children adicionales a la colección, se aplica una LayoutTransform o se llama al método UpdateLayout.

Este proceso, y los medios por los que se invoca, se define con mayor detalle en las secciones siguientes.

Rectángulos de selección de elementos

Al pensar en el diseño de una aplicación en Windows Presentation Foundation (WPF), es importante entender el rectángulo de selección que rodea todos los elementos. Esta abstracción ayuda a comprender el comportamiento del sistema de diseño. Cada FrameworkElement utilizado por el sistema de diseño se puede considerar como un rectángulo que se inserta en una partición del diseño. Se expone una clase, LayoutInformation, que puede devolver los límites geométricos de la asignación de diseño de un elemento, o su ranura. El sistema, calculando el espacio de pantalla disponible, determina el tamaño de ese rectángulo, el tamaño de cualquier restricción, las propiedades específicas del diseño, como el margen y el relleno, y el comportamiento individual del elemento Panel primario. Al procesar estos datos, el sistema puede calcular la posición de todos los elementos secundarios de un Panel determinado. Es importante recordar que las características de tamaño definidas en el elemento primario (como un Border) afectan a sus elementos secundarios.

Como ejemplo, tomemos el siguiente escenario de diseño simple.

Cuadrícula típica sin rectángulo de selección superpuesto.

Este diseño se puede lograr utilizando el Lenguaje de marcado de aplicaciones extensible (XAML) siguiente.

<Grid Name="myGrid" Background="LightSteelBlue" Height="150">
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="250"/>
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
    <RowDefinition />
  </Grid.RowDefinitions>
  <TextBlock Name="txt1" Margin="5" FontSize="16" FontFamily="Verdana" Grid.Column="0" Grid.Row="0">Hello World!</TextBlock>
  <Button Click="getLayoutSlot1" Width="125" Height="25" Grid.Column="0" Grid.Row="1">Show Bounding Box</Button>
  <TextBlock Name="txt2" Grid.Column="1" Grid.Row="2"/>
</Grid>

El elemento TextBlock solitario se hospeda dentro de una Grid. Aunque el texto rellena sólo la esquina superior izquierda de la columna en la que se ha colocado, en realidad el espacio asignado para TextBlock es mucho mayor. El rectángulo de selección de cualquier objeto FrameworkElement se puede recuperar utilizando el método GetLayoutSlot. Con este método, el rectángulo de selección del elemento TextBlock queda superpuesto (esto es posible porque el TextBlock se hospeda en una Grid, un elemento Panel que permite compartir las coordenadas de diseño).

El rectángulo de selección de TextBlock está visible ahora.

Como queda claro ahora por la línea blanca que lo rodea, la partición asignada al elemento TextBlock es, en realidad, mucho mayor que el espacio que rellena. Al agregar elementos adicionales a Grid, esta asignación se puede reducir o expandir, dependiendo del tipo y el tamaño de los elementos que se agregan.

La ranura de diseño de TextBlock se devuelve y convierte en un Path mediante el método GetLayoutSlot, una técnica que puede resultar útil para mostrar el rectángulo de selección de un elemento.

Private Sub getLayoutSlot1(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim myRectangleGeometry As New RectangleGeometry
    myRectangleGeometry.Rect = LayoutInformation.GetLayoutSlot(txt1)
    Dim myGeometryDrawing As New GeometryDrawing
    Dim myPath As New Path
    myPath.Data = myRectangleGeometry
    myPath.Stroke = Brushes.LightGoldenrodYellow
    myPath.StrokeThickness = 5
    Grid.SetColumn(myPath, 0)
    Grid.SetRow(myPath, 0)
    myGrid.Children.Add(myPath)
    txt2.Text = "LayoutSlot is equal to " + LayoutInformation.GetLayoutSlot(txt1).ToString()
End Sub
private void getLayoutSlot1(object sender, System.Windows.RoutedEventArgs e)
{
    RectangleGeometry myRectangleGeometry = new RectangleGeometry();
    myRectangleGeometry.Rect = LayoutInformation.GetLayoutSlot(txt1);
    GeometryDrawing myGeometryDrawing = new GeometryDrawing();
    Path myPath = new Path();
    myPath.Data = myRectangleGeometry;
    myPath.Stroke = Brushes.LightGoldenrodYellow;
    myPath.StrokeThickness = 5;
    Grid.SetColumn(myPath, 0);
    Grid.SetRow(myPath, 0);
    myGrid.Children.Add(myPath);
    txt2.Text = "LayoutSlot is equal to " + LayoutInformation.GetLayoutSlot(txt1).ToString();
}

Medir y organizar elementos secundarios

Cuando se representa el contenido de un objeto Window, se invoca el sistema del diseño automáticamente. Para mostrar el contenido, el Content de la ventana debe definir un Panel raíz que sirve para definir un marco que permite organizar los miembros de Children en la pantalla. Consulte Elementos de panel y comportamientos de diseño personalizado para obtener una lista de elementos Panel disponibles e información sobre cómo crear elementos de diseño personalizados.

El primer paso del diseño es la medición, que evalúa cada miembro de la colección Children. El proceso comienza con una llamada al método Measure. Se llama a este método dentro de la implementación del elemento Panel primario y no es preciso llamarla explícitamente para que el diseño tenga lugar.

En primer lugar, se evalúan las propiedades de tamaño nativas de UIElement, como Clip y Visibility. Esto genera un valor denominado constraintSize, que se pasa a MeasureCore.

En segundo lugar, se procesan las propiedades de marco definidas en FrameworkElement, lo que afecta al valor de constraintSize. Estas propiedades suelen a describir las características de tamaño del UIElement subyacente, como Height, Width, Margin y Style. Cada una de estas propiedades puede modificar el espacio necesario para mostrar el elemento. A continuación, se llama a MeasureOverride con constraintSize como parámetro.

Nota

Existe una diferencia entre las propiedades de Height y Width, y ActualHeight y ActualWidth. Por ejemplo, la propiedad ActualHeight es un valor calculado que se basa en otras entradas de alto y en el sistema de diseño. El propio sistema del diseño establece el valor, basándose en un paso de representación real; por consiguiente, puede existir un pequeño desfase con respecto al valor establecido de propiedades como Height, que constituyen la base del cambio de entrada.

Dado que ActualHeight es un valor calculado, debe tener en cuenta que puede haber varios cambios incrementados o registrados del mismo como resultado de las diversas operaciones realizadas por el sistema de diseño. El sistema de diseño puede calcular el espacio de medidas necesario para los elementos secundarios, las restricciones impuestas por el elemento principal, etc.

El objetivo definitivo del paso de la medida es que el elemento secundario determine su DesiredSize, lo que sucede durante la llamada a MeasureCore. Este valor lo almacena Measure para utilizarlo durante el proceso de organización del contenido.

El proceso de organización se inicia con una llamada al método Arrange. Durante el paso de organización, el elemento Panel primario genera un rectángulo que representa los límites del elemento secundario. Este valor se pasa al método ArrangeCore para procesarlo.

El método ArrangeCore evalúa el DesiredSize del elemento secundario y también cualquier margen adicional que pueda afectar al tamaño representado del elemento; a continuación, genera un arrangeSize que se pasa a ArrangeOverride del panel como parámetro. ArrangeOverride genera el finalSize del elemento secundario y, por último, el método ArrangeCore efectúa una última evaluación de las propiedades de desplazamiento, tales como el margen o la alineación, y coloca el elemento secundario dentro de su ranura de diseño. El elemento secundario no necesita rellenar el espacio asignado completo, y con frecuencia no lo hace. A continuación, el control se devuelve al Panel primario y el proceso del diseño se completa.

Elementos de panel y comportamientos de diseño personalizado

Windows Presentation Foundation (WPF) incluye un conjunto derivado de elementos Panel que habilitan numerosos diseños complejos. Los escenarios comunes, como apilar elementos, se consiguen con facilidad mediante el elemento StackPanel; otros diseños dinámicos más libres y complejos son posibles gracias a Canvas.

En la tabla siguiente se resumen los elementos de diseño disponibles.

Nombre del panel

Descripción

Canvas

Define una área en la que pueden colocarse explícitamente los elementos secundarios utilizando las coordenadas relativas al área del control Canvas.

DockPanel

Define un área en la que se pueden organizar horizontalmente o verticalmente los elementos secundarios, uno respecto al otro.

Grid

Define un área de cuadrícula flexible que se compone de columnas y filas.

StackPanel

Organiza los elementos secundarios en una única línea que se puede orientar horizontal o verticalmente.

VirtualizingPanel

Proporciona un marco para elementos Panel que "virtualizan" su recolección de datos secundarios. Ésta es una clase abstracta.

WrapPanel

Organiza los elementos secundarios secuencialmente de izquierda a derecha y traslada el contenido a la línea siguiente cuando alcanza el borde del cuadro contenedor. La clasificación siguiente se realiza secuencialmente de arriba abajo o de izquierda a derecha, en función del valor de la propiedad Orientation.

Para obtener ejemplos de código que muestran el uso de cada uno de estos elementos, consulte Ejemplos de diseño.

Para los escenarios que requieren un diseño de aplicación que no es posible utilizando cualquiera de los elementos Panel predefinidos, se pueden conseguir comportamientos de diseño personalizados heredando de Panel e invalidando los métodos MeasureOverride y ArrangeOverride. Para obtener un ejemplo, consulte Ejemplo Custom Radial Panel.

Consideraciones sobre el rendimiento del diseño

El diseño es un proceso recursivo. Cada elemento secundario de una colección Children se procesa durante cada invocación del sistema. Como resultado, debe evitarse activar el sistema cuando no es necesario. Las sugerencias siguientes pueden ayudarle a lograr un rendimiento más alto.

Las propiedades de dependencia cuyos valores pueden hacer que el sistema de diseño se inicialice se marcan con marcadores públicos. AffectsMeasure y AffectsArrange proporcionan pistas útiles sobre qué cambios del valor de la propiedad forzarán una actualización recursiva del sistema del diseño. En general, cualquier propiedad que puede afectar al tamaño del rectángulo de selección de un elemento debería establecer la marca AffectsMeasure en true. Para obtener más información, vea Información general sobre las propiedades de dependencia.

LayoutTransform puede ser una manera muy útil de afectar al contenido de una interfaz de usuario (UI). Sin embargo, si no es necesario que el efecto de la transformación afecte a la posición de otros elementos, es mejor utilizar RenderTransform en su lugar, ya que RenderTransform no invoca el sistema del diseño. LayoutTransform aplica su transformación y fuerza una actualización del diseño recursiva para tener en cuenta la nueva posición del elemento afectado.

Evite las llamadas innecesarias a UpdateLayout. Este método fuerza una actualización del diseño recursiva y no suele ser necesario. A menos que esté seguro de que se requiere una actualización completa, deje que el sistema de diseño llame a este método en su lugar.

Al tratar con una colección Children grande, puede ser conveniente utilizar VirtualizingStackPanel en lugar de un StackPanel normal. Al "virtualizar" la colección secundaria, VirtualizingStackPanel únicamente conserva en la memoria los objetos que se encuentran actualmente dentro del área de visualización del elemento primario. Como resultado, el rendimiento se mejora sustancialmente en la mayoría de los escenarios.

Pasos adicionales

Entender cómo se miden y organizan los elementos es el primer paso para entender el diseño como un sistema. Para obtener conocimientos más profundos sobre los elementos Panel disponibles, consulte Información general sobre elementos Panel. Para entender mejor las diversas propiedades de posición que pueden afectar al diseño, consulte Información general sobre alineación, márgenes y relleno. Para obtener un ejemplo de un elemento Panel personalizado, consulte Ejemplo Custom Radial Panel. Cuando esté preparado para aplicar todos estos conocimientos a la creación de una aplicación ligera, consulte Información general sobre Windows Presentation Foundation.

Vea también

Conceptos

Información general sobre elementos Panel

Información general sobre alineación, márgenes y relleno

Ajuste de píxeles en aplicaciones de WPF

XAMLPad

Optimizar el rendimiento: Presentación y diseño

Referencia

FrameworkElement

UIElement