LayoutLayout

Este tópico descreve o sistema de layout do Windows Presentation Foundation (WPF).This topic describes the Windows Presentation Foundation (WPF) layout system. Entender como e quando ocorrem cálculos de layout é essencial para a criação de interfaces de usuário no WPF.Understanding how and when layout calculations occur is essential for creating user interfaces in WPF.

Esse tópico contém as seguintes seções:This topic contains the following sections:

Caixas delimitadoras de elementosElement Bounding Boxes

Ao pensar no layout no WPF, é importante entender a caixa delimitadora que envolve todos os elementos.When thinking about layout in WPF, it is important to understand the bounding box that surrounds all elements. Cada FrameworkElement um consumido pelo sistema de layout pode ser considerado um retângulo que está encarado no layout.Each FrameworkElement consumed by the layout system can be thought of as a rectangle that is slotted into the layout. A LayoutInformation classe retorna os limites da alocação de layout de um elemento ou slot.The LayoutInformation class returns the boundaries of an element's layout allocation, or slot. O tamanho do retângulo é determinado pelo cálculo do espaço de tela disponível, pelo tamanho de quaisquer restrições, propriedades específicas de layout (como margem e preenchimento) e o comportamento individual do elemento pai Panel .The size of the rectangle is determined by calculating the available screen space, the size of any constraints, layout-specific properties (such as margin and padding), and the individual behavior of the parent Panel element. Processando esses dados, o sistema de layout é capaz de calcular a posição de todos os filhos de Panelum específico.Processing this data, the layout system is able to calculate the position of all the children of a particular Panel. É importante lembrar que as características de dimensionamento definidas no elemento pai, como a Border, afetam seus filhos.It is important to remember that sizing characteristics defined on the parent element, such as a Border, affect its children.

A ilustração a seguir mostra um layout simples.The following illustration shows a simple layout.

Captura de tela que mostra uma grade típica, sem a caixa delimitadora sobreposta.

Este layout pode ser alcançado usando o seguinte XAMLXAML.This layout can be achieved by using the following XAMLXAML.

<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>

Um único TextBlock elemento é hospedado em um Grid.A single TextBlock element is hosted within a Grid. Embora o texto preencha apenas o canto superior esquerdo da primeira coluna, o espaço alocado para o TextBlock é realmente muito maior.While the text fills only the upper-left corner of the first column, the allocated space for the TextBlock is actually much larger. A caixa delimitadora de FrameworkElement qualquer pode ser recuperada usando GetLayoutSlot o método.The bounding box of any FrameworkElement can be retrieved by using the GetLayoutSlot method. A ilustração a seguir mostra a caixa delimitadora TextBlock para o elemento.The following illustration shows the bounding box for the TextBlock element.

Captura de tela que mostra que a caixa delimitadora de TextBlock agora está visível.

Conforme mostrado pelo retângulo amarelo, o espaço alocado para o TextBlock elemento é realmente muito maior do que é exibido.As shown by the yellow rectangle, the allocated space for the TextBlock element is actually much larger than it appears. À medida que elementos adicionais são adicionados Gridao, essa alocação pode ser reduzida ou expandida, dependendo do tipo e do tamanho dos elementos que são adicionados.As additional elements are added to the Grid, this allocation could shrink or expand, depending on the type and size of elements that are added.

O slot de layout do TextBlock é convertido em um Path usando o GetLayoutSlot método.The layout slot of the TextBlock is translated into a Path by using the GetLayoutSlot method. Essa técnica pode ser útil para exibir a caixa delimitadora de um elemento.This technique can be useful for displaying the bounding box of an element.

private void getLayoutSlot1(object sender, System.Windows.RoutedEventArgs e)
{
    RectangleGeometry myRectangleGeometry = new RectangleGeometry();
    myRectangleGeometry.Rect = LayoutInformation.GetLayoutSlot(txt1);
    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();
}
Private Sub getLayoutSlot1(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim myRectangleGeometry As New RectangleGeometry
    myRectangleGeometry.Rect = LayoutInformation.GetLayoutSlot(txt1)
    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

O sistema de layoutThe Layout System

Em sua forma mais simples, o layout é um sistema recursivo que leva um elemento a ser dimensionado, posicionado e desenhado.At its simplest, layout is a recursive system that leads to an element being sized, positioned, and drawn. Mais especificamente, layout descreve o processo de medição e organização dos membros da Panel Children coleção de um elemento.More specifically, layout describes the process of measuring and arranging the members of a Panel element's Children collection. O layout é um processo intensivo.Layout is an intensive process. Quanto maior a Children coleção, maior será o número de cálculos que devem ser feitos.The larger the Children collection, the greater the number of calculations that must be made. A complexidade também pode ser introduzida com base no comportamento de layout Panel definido pelo elemento que possui a coleção.Complexity can also be introduced based on the layout behavior defined by the Panel element that owns the collection. Uma relativamente simples Panel, Canvascomo, pode ter um desempenho significativamente melhor do que um Gridmais Panelcomplexo, como o.A relatively simple Panel, such as Canvas, can have significantly better performance than a more complex Panel, such as Grid.

Cada vez que um filho UIElement altera sua posição, ele tem o potencial de disparar uma nova passagem pelo sistema de layout.Each time that a child UIElement changes its position, it has the potential to trigger a new pass by the layout system. Portanto, é importante compreender os eventos que podem invocar o sistema de layout, pois invocações desnecessárias podem levar a desempenho ruim do aplicativo.Therefore, it is important to understand the events that can invoke the layout system, as unnecessary invocation can lead to poor application performance. O exemplo a seguir descreve o processo que ocorre quando o sistema de layout é invocado.The following describes the process that occurs when the layout system is invoked.

  1. Um filho UIElement começa o processo de layout, primeiro tendo suas propriedades principais medidas.A child UIElement begins the layout process by first having its core properties measured.

  2. As propriedades de FrameworkElement dimensionamento definidas em são avaliadas, Widthcomo Margin, Heighte.Sizing properties defined on FrameworkElement are evaluated, such as Width, Height, and Margin.

  3. Panela lógica específica é aplicada, Dock como direção ou Orientationempilhamento.Panel-specific logic is applied, such as Dock direction or stacking Orientation.

  4. O conteúdo é organizado depois que todos os filhos são medidos.Content is arranged after all children have been measured.

  5. A Children coleção é desenhada na tela.The Children collection is drawn on the screen.

  6. O processo é invocado novamente se Children forem adicionados adicionais à coleção, um LayoutTransform será aplicado ou o UpdateLayout método será chamado.The process is invoked again if additional Children are added to the collection, a LayoutTransform is applied, or the UpdateLayout method is called.

Esse processo e como ele é invocado são definidos em mais detalhes nas seções a seguir.This process and how it is invoked are defined in more detail in the following sections.

Medindo e organizando filhosMeasuring and Arranging Children

O sistema de layout conclui duas passagens para cada membro da Children coleção, uma passagem de medida e uma passagem de organização.The layout system completes two passes for each member of the Children collection, a measure pass and an arrange pass. Cada filho Panel fornece seu próprio MeasureOverride e ArrangeOverride seus métodos para obter seu próprio comportamento de layout específico.Each child Panel provides its own MeasureOverride and ArrangeOverride methods to achieve its own specific layout behavior.

Durante o passo de medida, cada membro da Children coleção é avaliado.During the measure pass, each member of the Children collection is evaluated. O processo começa com uma chamada para o Measure método.The process begins with a call to the Measure method. Esse método é chamado dentro da implementação do elemento pai Panel e não precisa ser chamado explicitamente para que o layout ocorra.This method is called within the implementation of the parent Panel element, and does not have to be called explicitly for layout to occur.

Primeiro, as propriedades de tamanho nativo UIElement de são avaliadas, Clip como Visibilitye.First, native size properties of the UIElement are evaluated, such as Clip and Visibility. Isso gera um valor chamado constraintSize que é passado para MeasureCore.This generates a value named constraintSize that is passed to MeasureCore.

Em segundo lugar, as propriedades FrameworkElement da estrutura definidas em são processadas, constraintSizeo que afeta o valor de.Secondly, framework properties defined on FrameworkElement are processed, which affects the value of constraintSize. Essas propriedades geralmente descrevem as características de dimensionamento do UIElementsubjacente, como Height, Width Margin, e Style.These properties generally describe the sizing characteristics of the underlying UIElement, such as its Height, Width, Margin, and Style. Cada uma dessas propriedades pode alterar o espaço necessário para exibir o elemento.Each of these properties can change the space that is necessary to display the element. MeasureOverrideé chamado com constraintSize como um parâmetro.MeasureOverride is then called with constraintSize as a parameter.

Observação

Há uma diferença entre as Height Propriedades de ActualHeight e Width e e ActualWidth.There is a difference between the properties of Height and Width and ActualHeight and ActualWidth. Por exemplo, a ActualHeight propriedade é um valor calculado com base em outras entradas de altura e no sistema de layout.For example, the ActualHeight property is a calculated value based on other height inputs and the layout system. O valor é definido pelo próprio sistema de layout, com base em uma passagem de renderização real, e, portanto, pode atrasar um pouco atrás do valor definido Heightdas propriedades, como, que são a base da alteração de entrada.The value is set by the layout system itself, based on an actual rendering pass, and may therefore lag slightly behind the set value of properties, such as Height, that are the basis of the input change.

Como ActualHeight é um valor calculado, você deve estar ciente de que pode haver várias alterações relatadas e incrementadas para ele como resultado de várias operações pelo sistema de layout.Because ActualHeight is a calculated value, you should be aware that there could be multiple or incremental reported changes to it as a result of various operations by the layout system. O sistema de layout pode estar calculando o espaço de medição necessário para elementos filhos, as restrições do elemento pai e assim por diante.The layout system may be calculating required measure space for child elements, constraints by the parent element, and so on.

O objetivo final do passo de medida é que o filho Determine seu DesiredSize, que ocorre durante a MeasureCore chamada.The ultimate goal of the measure pass is for the child to determine its DesiredSize, which occurs during the MeasureCore call. O DesiredSize valor é armazenado pelo Measure para uso durante a passagem de organização de conteúdo.The DesiredSize value is stored by Measure for use during the content arrange pass.

A passagem Arrange começa com uma chamada para o Arrange método.The arrange pass begins with a call to the Arrange method. Durante a passagem de Arrange, o Panel elemento pai gera um retângulo que representa os limites do filho.During the arrange pass, the parent Panel element generates a rectangle that represents the bounds of the child. Esse valor é passado para o ArrangeCore método para processamento.This value is passed to the ArrangeCore method for processing.

O ArrangeCore método avalia o DesiredSize do filho e avalia quaisquer margens adicionais que possam afetar o tamanho renderizado do elemento.The ArrangeCore method evaluates the DesiredSize of the child and evaluates any additional margins that may affect the rendered size of the element. ArrangeCoregera um arrangeSize, que é passado para o ArrangeOverride método do Panel como um parâmetro.ArrangeCore generates an arrangeSize, which is passed to the ArrangeOverride method of the Panel as a parameter. ArrangeOverridegera o finalSize do filho.ArrangeOverride generates the finalSize of the child. Por fim, ArrangeCore o método faz uma avaliação final das propriedades de deslocamento, como margem e alinhamento, e coloca o filho em seu slot de layout.Finally, the ArrangeCore method does a final evaluation of offset properties, such as margin and alignment, and puts the child within its layout slot. O filho não precisa preencher o espaço inteiro alocado (e geralmente não faz isso).The child does not have to (and frequently does not) fill the entire allocated space. Em seguida, o controle é retornado Panel para o pai e o processo de layout é concluído.Control is then returned to the parent Panel and the layout process is complete.

Elementos de painel e comportamentos de layout personalizadosPanel Elements and Custom Layout Behaviors

O WPF inclui um grupo de elementos que derivam de Panel.WPF includes a group of elements that derive from Panel. Esses Panel elementos habilitam muitos layouts complexos.These Panel elements enable many complex layouts. Por exemplo, os elementos de empilhamento podem ser facilmente obtidos StackPanel usando o elemento, enquanto layouts de fluxo mais complexos e livres são possíveis Canvasusando um.For example, stacking elements can easily be achieved by using the StackPanel element, while more complex and free flowing layouts are possible by using a Canvas.

A tabela a seguir resume os elementos de Panel layout disponíveis.The following table summarizes the available layout Panel elements.

Nome do painelPanel name DescriçãoDescription
Canvas Define uma área na qual você pode posicionar explicitamente elementos filho por coordenadas em relação Canvas à área.Defines an area within which you can explicitly position child elements by coordinates relative to the Canvas area.
DockPanel Define uma área dentro da qual você pode organizar elementos filho horizontal ou verticalmente, uns em relação aos outros.Defines an area within which you can arrange child elements either horizontally or vertically, relative to each other.
Grid Define uma área de grade flexível que consiste em colunas e linhas.Defines a flexible grid area that consists of columns and rows.
StackPanel Organiza elementos filho em uma única linha que pode ser orientada horizontal ou verticalmente.Arranges child elements into a single line that can be oriented horizontally or vertically.
VirtualizingPanel Fornece uma estrutura para os elementos Panel que virtualizam os respectivos dados filho.Provides a framework for Panel elements that virtualize their child data collection. Esta é uma classe abstrata.This is an abstract class.
WrapPanel Coloca os elementos filho na posição sequencial da esquerda para a direita, quebrando o conteúdo para a próxima linha na borda da caixa delimitadora.Positions child elements in sequential position from left to right, breaking content to the next line at the edge of the containing box. A ordenação subsequente ocorre sequencialmente de cima para baixo ou da direita para a esquerda, dependendo do valor Orientation da propriedade.Subsequent ordering occurs sequentially from top to bottom or right to left, depending on the value of the Orientation property.

Para aplicativos que exigem um layout que não é possível usando qualquer Panel um dos elementos predefinidos, os comportamentos de layout personalizados podem ser obtidos pela herança Panel e substituição MeasureOverride dos ArrangeOverride métodos e.For applications that require a layout that is not possible by using any of the predefined Panel elements, custom layout behaviors can be achieved by inheriting from Panel and overriding the MeasureOverride and ArrangeOverride methods.

Considerações sobre desempenho de layoutLayout Performance Considerations

O layout é um processo recursivo.Layout is a recursive process. Cada elemento filho em uma Children coleção é processado durante cada invocação do sistema de layout.Each child element in a Children collection gets processed during each invocation of the layout system. Como resultado, disparar o sistema de layout deve ser evitado quando não for necessário.As a result, triggering the layout system should be avoided when it is not necessary. As considerações a seguir podem ajudá-lo a melhorar o desempenho.The following considerations can help you achieve better performance.

  • Esteja ciente de quais alterações de valor da propriedade forçarão uma atualização recursiva realizada pelo sistema de layout.Be aware of which property value changes will force a recursive update by the layout system.

    As propriedades de dependência cujos valores podem fazer com que o sistema de layout seja inicializado são marcadas com sinalizadores públicos.Dependency properties whose values can cause the layout system to be initialized are marked with public flags. AffectsMeasuree AffectsArrange fornecem pistas úteis sobre quais alterações de valor de propriedade forçarão uma atualização recursiva pelo sistema de layout.AffectsMeasure and AffectsArrange provide useful clues as to which property value changes will force a recursive update by the layout system. Em geral, qualquer propriedade que possa afetar o tamanho da caixa delimitadora de um elemento deve ter AffectsMeasure um sinalizador definido como true.In general, any property that can affect the size of an element's bounding box should have a AffectsMeasure flag set to true. Para obter mais informações, consulte Visão geral sobre propriedades de dependência.For more information, see Dependency Properties Overview.

  • Quando possível, use um RenderTransform em vez de LayoutTransformum.When possible, use a RenderTransform instead of a LayoutTransform.

    Um LayoutTransform pode ser uma maneira muito útil de afetar o conteúdo de um UI (interface do usuário)user interface (UI).A LayoutTransform can be a very useful way to affect the content of a UI (interface do usuário)user interface (UI). No entanto, se o efeito da transformação não tiver que afetar a posição de outros elementos, será melhor usar um RenderTransform em vez disso, porque RenderTransform o não invoca o sistema de layout.However, if the effect of the transform does not have to impact the position of other elements, it is best to use a RenderTransform instead, because RenderTransform does not invoke the layout system. LayoutTransformaplica sua transformação e força uma atualização de layout recursivo para considerar a nova posição do elemento afetado.LayoutTransform applies its transformation and forces a recursive layout update to account for the new position of the affected element.

  • Evite chamadas desnecessárias para UpdateLayout.Avoid unnecessary calls to UpdateLayout.

    O UpdateLayout método força uma atualização de layout recursiva e frequentemente não é necessário.The UpdateLayout method forces a recursive layout update, and is frequently not necessary. A menos que você tenha certeza de que uma atualização completa é necessária, confie no sistema de layout para chamar esse método para você.Unless you are sure that a full update is required, rely on the layout system to call this method for you.

  • Ao trabalhar com uma grande Children coleção, considere usar um VirtualizingStackPanel em vez de um StackPanelregular.When working with a large Children collection, consider using a VirtualizingStackPanel instead of a regular StackPanel.

    Ao virtualizar a coleção filho, VirtualizingStackPanel o só mantém os objetos na memória que estão no visor do pai.By virtualizing the child collection, the VirtualizingStackPanel only keeps objects in memory that are currently within the parent's ViewPort. Como resultado, o desempenho é significativamente melhorado na maioria dos cenários.As a result, performance is substantially improved in most scenarios.

Renderização subpixel e arredondamento de layoutSub-pixel Rendering and Layout Rounding

O sistema de gráficos do WPF usa unidades independentes de dispositivo para habilitar a resolução e a independência do dispositivo.The WPF graphics system uses device-independent units to enable resolution and device independence. Cada pixel independente de dispositivo é dimensionado automaticamente com a configuração de pontos por polegada (DPI) do sistema.Each device independent pixel automatically scales with the system's dots per inch (dpi) setting. Isso fornece aos aplicativos WPF um dimensionamento adequado para diferentes configurações de dpi e torna o aplicativo ciente de DPI automaticamente.This provides WPF applications proper scaling for different dpi settings and makes the application automatically dpi-aware.

No entanto, essa independência de DPI pode criar renderização de borda irregular devido à suavização de serrilhado.However, this dpi independence can create irregular edge rendering because of anti-aliasing. Esses artefatos, geralmente vistos como bordas desfocadas ou semitransparentes, podem ocorrer quando o local de uma borda está no meio de um pixel de dispositivo, em vez de entre os pixels de dispositivo.These artifacts, typically seen as blurry or semi-transparent edges, can occur when the location of an edge falls in the middle of a device pixel instead of between device pixels. O sistema de layout fornece uma maneira de compensar isso com o arredondamento de layout.The layout system provides a way to adjust for this with layout rounding. O arredondamento de layout ocorre quando o sistema de layout arredonda valores de pixel não integrais durante a passagem de layout.Layout rounding is where the layout system rounds any non-integral pixel values during the layout pass.

O arredondamento de layout é desabilitado por padrão.Layout rounding is disabled by default. Para habilitar o arredondamento de layout UseLayoutRounding , defina true a propriedade FrameworkElementcomo on any.To enable layout rounding, set the UseLayoutRounding property to true on any FrameworkElement. Como essa é uma propriedade de dependência, o valor será propagado para todos os filhos na árvore visual.Because it is a dependency property, the value will propagate to all the children in the visual tree. Para habilitar o arredondamento de layout para a interface UseLayoutRounding do true usuário inteira, defina como no contêiner raiz.To enable layout rounding for the entire UI, set UseLayoutRounding to true on the root container. Para ver um exemplo, consulte UseLayoutRounding.For an example, see UseLayoutRounding.

NovidadesWhat's Next

Entender como os elementos são medidos e organizados é o primeiro passo para entender o layout.Understanding how elements are measured and arranged is the first step in understanding layout. Para obter mais informações sobre os Panel elementos disponíveis, consulte visão geral dos painéis.For more information about the available Panel elements, see Panels Overview. Para compreender melhor as várias propriedades de posicionamento que podem afetar o layout, consulte Visão geral de alinhamento, margens e preenchimento.To better understand the various positioning properties that can affect layout, see Alignment, Margins, and Padding Overview. Quando estiver pronto para colocá-lo em um aplicativo leve, consulte passo a passos: Meu primeiro aplicativode área de trabalho do WPF.When you are ready to put it all together in a lightweight application, see Walkthrough: My first WPF desktop application.

Consulte tambémSee also