🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
ViewInView
This page was created by Charles on 2024-07-18. Last edited by Wikiadmin on 2026-07-29.

ViewInView lets you render a rooted ViewModel inside another ViewModel, for developers who need a custom detail layout for associated objects instead of a nested table grid.

Use ViewInView when a parent view must show one or more related objects with their own designed controls. The mounted ViewModel becomes part of the enclosing view at the position of the ViewInView widget.

For example, a Category view can show each related Product using a compact Product view with product attributes and a read-only association control, rather than showing Products as rows in a standard nested grid.

How ViewInView works

ViewInView uses the mount strategy to add nested ViewModels. A mounted ViewModel is merged into the view where the ViewInView widget is placed.

The widget needs two pieces of information:

Setting Purpose Category and Product example
Data expression Identifies the object or collection that the mounted ViewModel will receive. Follow the Category-to-Products association so that the widget receives the Category's products.
ViewModel Identifies the rooted ViewModel used to render each received object. Select a ProductDetail ViewModel rooted in Product.

If the data expression returns a collection, ViewInView renders a mounted view for each object in that collection. If it returns one object, it can render one mounted view. The mounted controls are functional as ordinary controls, but saving is handled in the context of the enclosing view.

Before you start

Create the ViewModel that you want to mount.

  1. In MDriven Designer, create a ViewModel typed to the class that will be displayed. For the example, create a ViewModel typed to Product.
  2. Make the ViewModel rooted for instance attributes. A rooted ViewModel receives a specific instance of its typed class; this is required when the mounted view displays attributes of that instance.
  3. Add and arrange the attributes and association controls that the mounted layout needs. For example, add Product Name, Product Number, and a read-only control for a related object.
  4. Size the layout for its intended use. When the mounted view is repeated in a parent view, a compact row-sized layout is usually easier to read than a full document layout.

For the difference between rooted and non-rooted ViewModels, see MDrivenStart:MDrivenStart DefineViews.

Add a ViewInView widget

  1. Open the parent ViewModel in MDriven Designer. For example, open the ViewModel rooted in Category.
  2. Select ViewInView in the options on the right side of the ViewModel editor.
  3. Draw the ViewInView widget in the location where the related data should appear. You can also add ViewInView from the ViewModel context menu.
  4. Set the widget's Column Name. Use a name that describes the mounted content, such as Products.
  5. Set the expression that loads the data for the mounted ViewModel. In the Category example, use the association that follows from the current Category to its Products.
  6. Set the ViewModel property to the rooted Product ViewModel created earlier.
  7. Run the view and verify that each related Product is rendered with the designed Product layout rather than as a nested grid row.

When arranging a repeated mounted view, make adjacent controls reach the intended layout boundary. In particular, controls that should define the bottom of the repeated layout need to touch that boundary so the rendering engine can extend the layout correctly.

Example: display products under a category

Assume these model concepts:

  • Category has an association to Products.
  • Product has attributes such as Name and Number.
  • ProductDetail is a ViewModel rooted in Product.

Configure the Category ViewModel as follows:

Item Configuration
Mounted ViewModel ProductDetail, rooted in Product
ViewInView column name Products
Data expression The Category-to-Products association
Result The Category view displays one ProductDetail layout for each related Product.

This keeps the Product presentation in ProductDetail. If you later add a Product attribute to that layout, every ViewInView location that mounts ProductDetail uses the updated presentation.

Select a view dynamically

The expression that chooses the ViewModel can be data-dependent. This lets different objects in the same collection use different mounted ViewModels.

For example, create two rooted ViewModels for Product:

  • ProductDetail for the normal compact Product presentation.
  • ProductAutoFormDetail for an alternative presentation.

Use a data-dependent rule so that a Product with a particular attribute value selects ProductAutoFormDetail and other Products select ProductDetail. At runtime, changing the deciding attribute can replace the mounted layout with the other ViewModel. This allows polymorphic presentations within one parent UI.

A dynamically selected ViewModel may not be resolvable in the designer before runtime. If the editor reports that no ViewModel is found while the selection depends on runtime data, verify the expression and test the view at runtime.

Design patterns

Goal ViewInView approach
Show related objects without a grid Mount a compact rooted detail ViewModel for the associated collection.
Show different layouts for different rows Choose the mounted ViewModel with a data-dependent expression.
Show shared fields and type-specific fields Mount a common view or select a different view for each subtype or data condition.
Build a wizard-like area Use the current state to select the mounted ViewModel for the current step; navigation can change the state and therefore the displayed content.
Replace one area of a form Provide one object to ViewInView and change either the supplied data or the selected ViewModel when the user changes context.

Keep the mounted views focused. A ViewInView layout is easier to maintain when each mounted ViewModel has one clear purpose, such as a product summary, a type-specific detail panel, or one wizard step.

Test the result

Use Turnkey Live View to inspect the running UI while you adjust the parent and mounted ViewModels. Verify these cases:

  1. The parent data expression returns the intended object or collection.
  2. The mounted ViewModel is rooted in the class of the returned objects.
  3. Each repeated mounted layout has the expected controls and size.
  4. Changes in mounted controls participate in saving from the enclosing view.
  5. Each data condition selects the expected ViewModel when you use dynamic view selection.

ViewInView configures generated ViewModel UI. If you are replacing generated Turnkey HTML or building a custom front end, use the relevant view-override and metadata documentation instead of duplicating that implementation in the mounted view.

See also