МакетLayout

В этом разделе описывается система макета Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF).This topic describes the Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) layout system. Для создания пользовательских интерфейсов в WPFWPF важно понимание того, как и когда происходят вычисления макета.Understanding how and when layout calculations occur is essential for creating user interfaces in WPFWPF.

В этом разделе содержатся следующие подразделы.This topic contains the following sections:

Ограничивающие прямоугольники элементаElement Bounding Boxes

При планировании макета в WPFWPF важно понимать принцип функционирования ограничивающих прямоугольников, которые окружают все элементы.When thinking about layout in WPFWPF, it is important to understand the bounding box that surrounds all elements. Каждый FrameworkElement потребления макета системы может рассматриваться как прямоугольник, вставленный в макет.Each FrameworkElement consumed by the layout system can be thought of as a rectangle that is slotted into the layout. LayoutInformation Класс возвращает границы элемента макета, или ячейки.The LayoutInformation class returns the boundaries of an element's layout allocation, or slot. Размер прямоугольника определяется путем вычисления доступного пространства на экране, размера любых ограничений, свойств макета (например, поля и заполнение) и также индивидуального поведения родительского 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. Обработка этих данных, система макета имеет возможность вычислить положение всех потомков конкретного Panel.Processing this data, the layout system is able to calculate the position of all the children of a particular Panel. Важно помнить, что характеристики размеров, определенные в родительском элементе, например Border, влияют на его дочерние элементы.It is important to remember that sizing characteristics defined on the parent element, such as a Border, affect its children.

На рисунке ниже представлен простой макет.The following illustration shows a simple layout.

Снимок экрана, показывающий обычная сетка, без обрамляющего прямоугольника.

Этот макет можно получить с помощью приведенного ниже кода 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>

Один TextBlock элемент размещается внутри Grid.A single TextBlock element is hosted within a Grid. Хотя текст заполняет только верхний левый угол первого столбца, выделенное пространство для TextBlock самом деле гораздо больше.While the text fills only the upper-left corner of the first column, the allocated space for the TextBlock is actually much larger. Ограничивающий прямоугольник любого FrameworkElement можно получить с помощью GetLayoutSlot метод.The bounding box of any FrameworkElement can be retrieved by using the GetLayoutSlot method. На следующем рисунке показан ограничивающий прямоугольник для TextBlock элемент.The following illustration shows the bounding box for the TextBlock element.

Снимок экрана, показывающий, что ограничивающий прямоугольник для TextBlock теперь является видимым.

Как показано желтым прямоугольником, выделенное пространство для TextBlock элемент деле гораздо больше, чем кажется.As shown by the yellow rectangle, the allocated space for the TextBlock element is actually much larger than it appears. При добавлении дополнительных элементов Grid, это выделение может сжиматься или растягиваться в зависимости от типа и размера добавляемых элементов.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.

Ячейка макета элемента TextBlock преобразуется в Path с помощью GetLayoutSlot метод.The layout slot of the TextBlock is translated into a Path by using the GetLayoutSlot method. Этот способ может быть полезен для отображения ограничивающего прямоугольника элемента.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

Система макетаThe Layout System

В самом простом случае макет является рекурсивной системой, которая изменяет размер и расположение элемента и отображает его на экране.At its simplest, layout is a recursive system that leads to an element being sized, positioned, and drawn. В частности, макет описывает процесс измерения и упорядочения объекта Panel элемента Children коллекции.More specifically, layout describes the process of measuring and arranging the members of a Panel element's Children collection. Макет является интенсивным процессом.Layout is an intensive process. Чем больше Children коллекции, тем больше количества вычислений, которые должны выполняться.The larger the Children collection, the greater the number of calculations that must be made. Сложность может также быть вызвана поведением макета, определяемым Panel элемент, которому принадлежит коллекция.Complexity can also be introduced based on the layout behavior defined by the Panel element that owns the collection. Относительно простой Panel, такие как Canvas, может иметь лучшую производительность, чем более сложный Panel, такие как Grid.A relatively simple Panel, such as Canvas, can have significantly better performance than a more complex Panel, such as Grid.

Каждый раз, дочерний элемент UIElement изменяет свое положение, он потенциально имеет возможность запустить новый проход системы макета.Each time that a child UIElement changes its position, it has the potential to trigger a new pass by the layout system. Таким образом, важно понимать события, которые может вызывать система макета, так как ненужный вызов может привести к ухудшению производительности приложения.Therefore, it is important to understand the events that can invoke the layout system, as unnecessary invocation can lead to poor application performance. Далее описывается процесс, который происходит при вызове системы макета.The following describes the process that occurs when the layout system is invoked.

  1. Дочерний элемент UIElement начинает процесс разметки первым, задав его основные измеряемые свойства.A child UIElement begins the layout process by first having its core properties measured.

  2. Свойства, определенные для размера FrameworkElement вычисляются, такие как Width, Height, и Margin.Sizing properties defined on FrameworkElement are evaluated, such as Width, Height, and Margin.

  3. Panel-применяется специальная логика, такие как Dock направление или наложение Orientation.Panel-specific logic is applied, such as Dock direction or stacking Orientation.

  4. Содержимое располагается после того, как все потомки были измерены.Content is arranged after all children have been measured.

  5. Children Коллекции рисуется на экране.The Children collection is drawn on the screen.

  6. Процесс вызывается снова, если дополнительные Children добавляются в коллекцию LayoutTransform применяется, или UpdateLayout вызывается метод.The process is invoked again if additional Children are added to the collection, a LayoutTransform is applied, or the UpdateLayout method is called.

Этот процесс и порядок его вызова более подробно рассматриваются в следующих разделах.This process and how it is invoked are defined in more detail in the following sections.

Измерение и расположение дочерних элементовMeasuring and Arranging Children

Система макета совершает два прохода для каждого члена Children коллекции, проход измерения и проход компоновки.The layout system completes two passes for each member of the Children collection, a measure pass and an arrange pass. Каждый дочерний элемент Panel предоставляет собственное MeasureOverride и ArrangeOverride способа установления собственное поведение конкретного макета.Each child Panel provides its own MeasureOverride and ArrangeOverride methods to achieve its own specific layout behavior.

При проходе измерения каждый член Children коллекции оценивается.During the measure pass, each member of the Children collection is evaluated. Процесс начинается с вызова Measure метод.The process begins with a call to the Measure method. Этот метод вызывается в реализации родительского Panel элемент и не обязательно должен вызываться явным образом для вызова макета.This method is called within the implementation of the parent Panel element, and does not have to be called explicitly for layout to occur.

Во-первых, собственный размер свойства UIElement вычисляются, такие как Clip и Visibility.First, native size properties of the UIElement are evaluated, such as Clip and Visibility. Это создает значение с именем constraintSize передаваемый MeasureCore.This generates a value named constraintSize that is passed to MeasureCore.

Во-вторых, определенные свойства исполняющей среды на FrameworkElement обрабатываются, что негативно влияет на значение constraintSize.Secondly, framework properties defined on FrameworkElement are processed, which affects the value of constraintSize. Эти свойства в основном описывают размерные характеристики базового UIElement, такие как его Height, Width, Margin, и Style.These properties generally describe the sizing characteristics of the underlying UIElement, such as its Height, Width, Margin, and Style. Каждое из этих свойств может изменить пространство, необходимое для отображения элемента.Each of these properties can change the space that is necessary to display the element. MeasureOverride Затем вызывается с constraintSize как параметр.MeasureOverride is then called with constraintSize as a parameter.

Примечание

Есть разница между свойствами Height и Width и ActualHeight и ActualWidth.There is a difference between the properties of Height and Width and ActualHeight and ActualWidth. Например ActualHeight свойство имеет значение, вычисленное на основе других вводимых высот и системы макета.For example, the ActualHeight property is a calculated value based on other height inputs and the layout system. Значение задается самой системой макета в зависимости от фактического прохода отрисовки и поэтому может отставать немного набор значений свойств, таких как Height, которые являются основой для изменения ввода.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.

Поскольку ActualHeight является вычисляемым значением, следует иметь в виду, могут производиться многократные или добавочные сообщаемые изменения к нему в результате различных операций системой макета.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. Система макета может вычислять требуемое место измерения для дочерних элементов, ограничения родительского элемента и т. д.The layout system may be calculating required measure space for child elements, constraints by the parent element, and so on.

Является конечной целью прохода измерения для дочернего элемента для определения его DesiredSize, которое происходит во время MeasureCore вызова.The ultimate goal of the measure pass is for the child to determine its DesiredSize, which occurs during the MeasureCore call. DesiredSize Значение сохраняется командлетом Measure для использования во время компоновки содержимого.The DesiredSize value is stored by Measure for use during the content arrange pass.

Процесс компоновки начинается с вызова Arrange метод.The arrange pass begins with a call to the Arrange method. Во время прохода компоновки родительский Panel элемент создает прямоугольник, представляющий границы потомка.During the arrange pass, the parent Panel element generates a rectangle that represents the bounds of the child. Это значение передается ArrangeCore метод для обработки.This value is passed to the ArrangeCore method for processing.

ArrangeCore Метод оценивает DesiredSize дочернего элемента и оценивает все дополнительные поля, которые могут повлиять на отображаемый размер элемента.The ArrangeCore method evaluates the DesiredSize of the child and evaluates any additional margins that may affect the rendered size of the element. ArrangeCore Создает arrangeSize, который передается ArrangeOverride метод Panel как параметр.ArrangeCore generates an arrangeSize, which is passed to the ArrangeOverride method of the Panel as a parameter. ArrangeOverride Создает finalSize дочернего элемента.ArrangeOverride generates the finalSize of the child. Наконец ArrangeCore метод выполняет окончательную оценку свойств смещения, таких как поле и выравнивание и помещает дочерний объект в его ячейку макета.Finally, the ArrangeCore method does a final evaluation of offset properties, such as margin and alignment, and puts the child within its layout slot. Дочерний объект не должен обязательно заполнять все выделенное пространство (и в большинстве случаев не делает этого).The child does not have to (and frequently does not) fill the entire allocated space. Затем управление возвращается родительский Panel и обработка макета завершается.Control is then returned to the parent Panel and the layout process is complete.

Элементы панели и пользовательские расширения функциональности макетаPanel Elements and Custom Layout Behaviors

WPFWPF включает в себя группу элементов, которые являются производными от Panel.includes a group of elements that derive from Panel. Эти Panel элементы включают многие сложные макеты.These Panel elements enable many complex layouts. Например, наложение элементов можно легко реализовать с помощью StackPanel элемент, хотя более сложные и свободно располагаемые макеты создаются с помощью Canvas.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.

В следующей таблице перечислены доступные макета Panel элементов.The following table summarizes the available layout Panel elements.

Имя панелиPanel name ОписаниеDescription
Canvas Определяет область, внутри которой можно явным образом разместить дочерние элементы с помощью координатах по отношению к Canvas области.Defines an area within which you can explicitly position child elements by coordinates relative to the Canvas area.
DockPanel Определяет область, в которой можно горизонтально либо вертикально упорядочивать дочерние элементы относительно друг друга.Defines an area within which you can arrange child elements either horizontally or vertically, relative to each other.
Grid Задание области с таблицей переменного размера, состоящей из столбцов и строк.Defines a flexible grid area that consists of columns and rows.
StackPanel Выравнивает дочерние элементы в одну линию, ориентированную горизонтально или вертикально.Arranges child elements into a single line that can be oriented horizontally or vertically.
VirtualizingPanel Предоставляет платформу для Panel элементов, виртуализирующих свои дочерние коллекции данных.Provides a framework for Panel elements that virtualize their child data collection. Этот класс является абстрактным.This is an abstract class.
WrapPanel Размещает дочерние элементы последовательно слева направо, перенося содержимое на следующую строку на краю содержащего поля.Positions child elements in sequential position from left to right, breaking content to the next line at the edge of the containing box. Дальнейшее упорядочивание происходит последовательно сверху вниз или слева направо в зависимости от значения Orientation свойство.Subsequent ordering occurs sequentially from top to bottom or right to left, depending on the value of the Orientation property.

Для приложений, которым требуется макет, который не поддерживается с помощью любого из предварительно определенных Panel элементы, пользовательские расширения функциональности макета можно получить путем наследования из Panel и переопределение MeasureOverride и ArrangeOverride методы.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. Пример см. на странице Пример Custom Radial Panel.For an example, see Custom Radial Panel Sample.

Вопросы производительности макетаLayout Performance Considerations

Макет является рекурсивным процессом.Layout is a recursive process. Каждый дочерний элемент в Children коллекции обрабатываются при каждом вызове системы макета.Each child element in a Children collection gets processed during each invocation of the layout system. Это означает, что следует избегать запуска системы макета при отсутствии необходимости.As a result, triggering the layout system should be avoided when it is not necessary. Выполнение приведенных ниже рекомендаций поможет добиться более высокой производительности.The following considerations can help you achieve better performance.

  • Следует учитывать, что определенные изменения значений свойств могут привести к выполнению системой макета рекурсивного обновления.Be aware of which property value changes will force a recursive update by the layout system.

    Свойства зависимостей, значения которых могут привести к инициализации системы макета, помечаются общими флагами.Dependency properties whose values can cause the layout system to be initialized are marked with public flags. AffectsMeasure и AffectsArrange предоставляют полезные указания о том, какое свойство изменяется вызовут рекурсивное обновление системой макета.AffectsMeasure and AffectsArrange provide useful clues as to which property value changes will force a recursive update by the layout system. Как правило, должен иметь любое свойство, которое может повлиять на размер ограничивающего прямоугольника элемента AffectsMeasure флаг задано значение true.In general, any property that can affect the size of an element's bounding box should have a AffectsMeasure flag set to true. Дополнительные сведения см. в обзоре свойств зависимостей.For more information, see Dependency Properties Overview.

  • По возможности используйте RenderTransform вместо LayoutTransform.When possible, use a RenderTransform instead of a LayoutTransform.

    Объект LayoutTransform может быть очень полезным инструментом для определения содержимого пользовательский интерфейсuser interface (UI).A LayoutTransform can be a very useful way to affect the content of a пользовательский интерфейсuser interface (UI). Тем не менее, если результат преобразования не влияет на положение других элементов, лучше всего использовать RenderTransform вместо этого, так как RenderTransform не вызывает систему макета.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. LayoutTransform применяет свое преобразование и вызывает рекурсивное обновление макета для учета нового положения затронутого элемента.LayoutTransform applies its transformation and forces a recursive layout update to account for the new position of the affected element.

  • Избегайте ненужных вызовов UpdateLayout.Avoid unnecessary calls to UpdateLayout.

    UpdateLayout Метод вызывает рекурсивное обновление макета и часто не является обязательным.The UpdateLayout method forces a recursive layout update, and is frequently not necessary. Если нет уверенности в необходимости обновления, следует предоставить вызов этого метода системе макета.Unless you are sure that a full update is required, rely on the layout system to call this method for you.

  • При работе с большим Children коллекции, рассмотрите возможность использования VirtualizingStackPanel вместо обычного StackPanel.When working with a large Children collection, consider using a VirtualizingStackPanel instead of a regular StackPanel.

    Благодаря виртуализации дочернюю коллекцию VirtualizingStackPanel только сохраняет объекты в памяти, которые в настоящее время находятся внутри элемента ViewPort родительского элемента.By virtualizing the child collection, the VirtualizingStackPanel only keeps objects in memory that are currently within the parent's ViewPort. В результате этого производительность значительно увеличивается в большинстве сценариев.As a result, performance is substantially improved in most scenarios.

Субпиксельная отрисовка и округление макетаSub-pixel Rendering and Layout Rounding

Графическая система WPFWPF использует аппаратно-независимые модули для обеспечения независимости от разрешения и устройства.The WPFWPF graphics system uses device-independent units to enable resolution and device independence. Каждый аппаратно-независимый пиксель автоматически масштабируется согласно параметру точек на дюйм (dpi)dots per inch (dpi) системы.Each device independent pixel automatically scales with the system's точек на дюйм (dpi)dots per inch (dpi) setting. Это обеспечивает приложениям WPFWPF корректное масштабирование для различных параметров точек на дюймdpi и автоматически предоставляет приложениям поддержку точек на дюймdpi.This provides WPFWPF applications proper scaling for different точек на дюймdpi settings and makes the application automatically точек на дюймdpi-aware.

Однако такая независимость от точек на дюймdpi может привести к неравномерной отрисовке границ из-за сглаживания.However, this точек на дюймdpi independence can create irregular edge rendering because of anti-aliasing. Эти эффекты, обычно выглядящие как смазанные или полупрозрачные границы, могут появиться, когда положение границы попадает в середину пикселя устройства, а не между пикселями.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. В системе макета имеется способ настройки границ с помощью округления макета.The layout system provides a way to adjust for this with layout rounding. Округление макета заключается в том, что система макета округляет все нецелочисленные значения пикселей во время прохода макета.Layout rounding is where the layout system rounds any non-integral pixel values during the layout pass.

По умолчанию округление макета отключено.Layout rounding is disabled by default. Чтобы включить округление макета, задайте UseLayoutRounding свойства true на любом FrameworkElement.To enable layout rounding, set the UseLayoutRounding property to true on any FrameworkElement. Так как это свойство зависимости, значение будет распространено на все дочерние объекты в визуальном дереве.Because it is a dependency property, the value will propagate to all the children in the visual tree. Чтобы включить округление макета для всего пользовательского интерфейса, задайте UseLayoutRounding для true в корневом контейнере.To enable layout rounding for the entire UI, set UseLayoutRounding to true on the root container. Пример см. в разделе UseLayoutRounding.For an example, see UseLayoutRounding.

Что дальше?What's Next

Понимание механизма измерения и упорядочивания элементов — это первый шаг к пониманию макета.Understanding how elements are measured and arranged is the first step in understanding layout. Дополнительные сведения о доступных Panel элементов, см. в разделе Общие сведения о панелях.For more information about the available Panel elements, see Panels Overview. Чтобы лучше понять различные свойства размещения, которые могут повлиять на макет, см. раздел Общие сведения о свойствах Alignment, Margin, Padding.To better understand the various positioning properties that can affect layout, see Alignment, Margins, and Padding Overview. Пример настраиваемого Panel элемент, см. в разделе пример Custom Radial Panel.For an example of a custom Panel element, see Custom Radial Panel Sample. Когда будете готовы к помещению все вместе в облегченное приложение, см. в разделе Пошаговое руководство: Создание первого классического приложения WPF.When you are ready to put it all together in a light-weight application, see Walkthrough: My first WPF desktop application.

См. такжеSee also