You use PlacingContainers in MDriven Designer to build responsive ViewModel layouts from nested boxes instead of fixed X and Y grid positions.
What PlacingContainers do
A PlacingContainer is a section of a ViewModel that contains columns and/or other PlacingContainers. It uses the same box-in-box layout principles as CSS FlexBox:
- The container controls how its direct children are placed.
- A child can be a ViewModel column, an action column, or another PlacingContainer.
- Nested containers let you describe a layout as sections, rows, and columns.
- In the web renderer, including Turnkey, MDriven renders this layout as HTML with FlexBox CSS. In the Designer and WPF application, MDriven uses its FlexBox renderer.
This approach is intended for layouts that must adapt when the available width changes. A traditional grid layout with fixed X and Y coordinates remains stable as the window narrows; a container layout can stack or wrap its content instead.
Understand the layout axes
The Direction of a PlacingContainer determines its main layout axis.
| Direction | Direct children are placed | The container normally fills in the perpendicular direction | Example |
|---|---|---|---|
| Row | Horizontally, from left to right | Vertically | Put a picture column and a details column beside each other. |
| Column | Vertically, from top to bottom | Horizontally | Put a header, a details section, and a list section one below another. |
For example, if a section should span the available width and contain a table below a header, set the parent container's Direction to Column. The header and table then stack vertically, while the column-direction container fills horizontally.
If a container does not appear to fill the width of the container above it, check its parent direction. By default, a container fills in the direction perpendicular to the parent's main axis, not necessarily in both directions.
Convert an existing ViewModel layout
When you start using PlacingContainers on a ViewModel, place the ViewModel's columns inside containers. Leaving columns outside a PlacingContainer makes the layout undefined because the former rendering grid is no longer the layout structure.
- Open the ViewModel in MDriven Designer.
- Add a root PlacingContainer to the ViewModel.
- Move every ViewModel column that belongs to the layout into the root container or into a child container.
- Select the root container and set Direction according to the overall layout:
- Use Column when major sections should appear from top to bottom.
- Use Row when major sections should appear side by side.
- Add child PlacingContainers for each logical section and move the appropriate columns into them.
- Save and test the layout at different widths in the target renderer.
For example, a person-editing ViewModel can use a root container with Direction Column. Put the name and command area in an upper child container, and put the HistoricOwnership grid in a lower child container. This keeps the grid below the editing fields rather than beside them.
Build layouts by nesting containers
Use one container for the page or section, then add child containers to express the grouping you want. The Designer preview indicates the selected container's direction, which helps you verify whether its children will be arranged across or down.
A common structure is:
Root container (Column)
Header and commands container (Row)
Save action
Other fields or actions
Details container (Row or Column)
Detail columns
Data container (Column)
Repeated-data layout
Do not rely on visual position alone when moving containers. A child container is placed after its preceding sibling within its parent. If a section appears in the wrong place, verify both its parent and the parent's Direction.
Control available space with Grow
Grow controls how a child uses available space along the parent's main axis. Use it when one section or column should take the remaining room.
For example, in a row that contains an image and fields:
- Set the image column to Grow = 0 so it does not consume the remaining horizontal space.
- Set the fields column to Grow = 1 so it takes the remaining horizontal space.
For a page whose root is a column, you can give a lower grid section Grow = 2 so that section fills available space in the vertical direction.
Remember that Grow follows the parent direction. In a Row, it affects horizontal distribution. In a Column, it affects vertical distribution.
Align and constrain items
Use the container's alignment settings to control how children are aligned across the perpendicular axis. For a column-direction container, setting Align Items to Stretch makes its direct children stretch across the available width.
Use a child's Self-align setting when that child needs a different alignment from its siblings. Self-align is useful for controlling a column's size or placement in the cross direction.
Minimum and maximum size limits apply in the relevant layout direction. For example, when an action button is inside a row, a maximum value constrains it in the row's horizontal direction. Apply limits to the intended child, not accidentally to its parent container.
Make a row wrap on narrow screens
A row does not become responsive only because it is inside a PlacingContainer. If its items cannot fit, enable wrapping on the relevant container so items can move to another line.
For example, a row of details fields can be configured to wrap. At a wide width, the fields appear beside each other. At a narrower width, later fields move below earlier fields instead of being compressed into an unusable row.
Test this behavior by resizing the rendered UI. A layout can look correct in the Designer at one size but require different grouping, Grow values, wrapping, or size constraints at another size.
Lay out repeated data and grids
For a grid or repeated-data area that needs a container-based layout, use at least two PlacingContainers:
- Add an outer PlacingContainer that holds all data items.
- Add a child PlacingContainer that defines the layout of one item or row.
- Set the outer container to Column when items should be listed one below another.
- Put the relevant value columns and action columns inside the per-row container.
- Set the row container's Direction, Grow, wrapping, and alignment according to how one item should respond to reduced width.
The outer container controls the list of items. The inner container controls the contents of each item. The Designer may show empty sample rows to preview the repeated layout.
This pattern also lets one data item use multiple visual rows. For example, put primary values and an action button in a first child container, then put secondary values in another child container below it. Each repeated item then renders as a compact multi-line block rather than a rigid single grid row.
A conventional grid can still resist responsive folding because its columns retain their space. Use a per-item container layout when you need fields to wrap or stack in a controlled way.
Design a fixed-and-flexible two-column row
FlexBox rows are independent. One row cannot make itself aware of the widths in another row. Therefore, do not expect image and field columns in separate rows to automatically line up based on their content.
To create a row with a fixed image area and a flexible fields area:
- Create a PlacingContainer with Direction Row.
- Put the image column and fields column inside it.
- Keep the image size fixed, or fixed for the relevant screen-size range.
- Set the image column to Grow = 0.
- Set the fields column to Grow = 1.
- Use Self-align on the columns when you need to control their cross-axis sizing.
If the image size must differ by screen size, use CSS media queries for those screen-size-specific values. The container layout does not make separate rows coordinate their column widths.
Actions in a container layout
Action columns are ordinary layout children once you move them into a PlacingContainer. You can place a save action at the top of a column-direction root container, before the sections it applies to.
For example, a Save action can use the expression selfVM.Save. Its enabled or visible state can be based on the ViewModel dirty list, such as selfVM.Dirtylist->isempty for a disable expression or selfVM.Dirtylist->notempty for a visible expression. You can also use the VisibleExpression's FollowEnable flag when the action should follow its enabled state.
In a repeated-data row, an action is evaluated in the context of the clicked row. A recurrent variable can therefore assign self to refer to that row's object.
Troubleshooting
| What you see | Likely cause | What to check |
|---|---|---|
| A section does not fill the expected width. | The parent direction fills only in the perpendicular direction by default. | Check whether the parent should use Direction Column, and review alignment and Grow. |
| Columns appear in an unexpected order or beside each other. | The parent container has Direction Row, or the children are in the wrong parent. | Check the selected container's direction and the child-container hierarchy. |
| The layout has errors after adding a root container. | Existing ViewModel columns remain outside the container structure. | Move all relevant columns into the root container or child containers. |
| A repeated-data layout does not respond as expected. | Only one container is being used, or the row layout is still a rigid grid. | Use an outer items container and an inner per-item container; enable wrapping where appropriate. |
| A row becomes too narrow instead of stacking. | Wrapping is not enabled, or minimum/maximum size limits prevent further shrinking. | Enable wrapping on the row and inspect constraints on its children. |
| A size limit affects too much of the layout. | The limit was set on a parent container rather than the intended control. | Select the specific child, such as the action button, and apply the constraint there. |
Learn by doing
Follow Training:Bootcamp:Chapter 8 for a guided exercise that adds a root PlacingContainer, moves columns into it, changes Row to Column, configures Grow, and creates child containers for responsive design. You can also watch the PlacingContainer walk-through to see nested containers, wrapping, and repeated-data layouts being assembled.
