レイアウト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>

1 つ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など、評価はWidthHeight、および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

レイアウト システムには、2 つのパスの各メンバーが完了すると、Childrenコレクション、測定パスと配置パス。The layout system completes two passes for each member of the Children collection, a measure pass and an arrange pass. それぞれの子Panel独自MeasureOverrideArrangeOverrideメソッドは独自の特定のレイアウト動作を実現するためにします。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など、評価はClipVisibilityします。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などのHeightWidthMargin、および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.

注意

プロパティの間の相違があるHeightWidthActualHeightActualWidthします。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をオーバーライドして、MeasureOverrideArrangeOverrideメソッド。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 Sample」 (カスタム放射状パネルのサンプル) を参照してください。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.

    ALayoutTransformの内容に影響を与える非常に便利なことができます、ユーザー インターフェイス (UI)user interface (UI)します。A LayoutTransform can be a very useful way to affect the content of a ユーザー インターフェイス (UI)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現在、親のビューポート内にあるメモリ内オブジェクトのみを保持します。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. これにより、異なる dpidpi 設定に対して WPFWPF アプリケーションに適切なスケーリングを提供し、アプリケーションを自動的に dpidpi 対応にします。This provides WPFWPF applications proper scaling for different dpidpi settings and makes the application automatically dpidpi-aware.

ただし、この dpidpi 非依存は、アンチエイリアシングのため、不規則なエッジ レンダリングが作成される場合があります。However, this dpidpi 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. レイアウトの UI 全体の丸め処理を有効にするには設定UseLayoutRoundingtrueルート コンテナーにします。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. レイアウトに影響を与えるさまざまな配置プロパティをより理解するには、「配置、余白、パディングの概要」を参照してください。To better understand the various positioning properties that can affect layout, see Alignment, Margins, and Padding Overview. カスタムの例については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