🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Cursored or Full Tree
This page was created by Stephanie on 2023-08-08. Last edited by Wikiadmin on 2026-07-29.

You can choose a full-tree or cursored ViewModel shape to control whether a client receives every reachable object or only the branch below the current selection; this page is for MDriven developers designing nested ViewModels.

Choose the graph shape before you build the UI

A ViewModel represents model objects in a structure that a client can render. When the ViewModel contains nested collections, the same model data can be shaped in two different ways:

Strategy What the ViewModel contains Best fit Main trade-off
Full tree All objects reached through every nesting. A UI that must render several branches at once, such as a tree. More objects are loaded and sent up front.
Cursored tree The root, each collection at the current path, and the objects below the selected item at each level. Master-detail editing where the user works in one branch at a time. The UI cannot render unselected sibling branches from data that has not been loaded.

The choice affects both the amount of data the server prepares and what a client-side UI can render without requesting or rebuilding data.

Example object graph

Assume this model relationship and data:

  • One Class1 object is the root.
  • The Class1 object has two Class2 objects.
  • Each Class2 object has two Class3 objects.
  • Each Class3 object has two Class4 objects.

The complete graph contains:

Level Number of objects
Class1 1
Class2 2
Class3 4
Class4 8
Total 15

For example, if the root is Class1 A, it may contain Class2 A1 and Class2 A2. Class2 A1 contains Class3 A1.1 and Class3 A1.2; Class2 A2 contains Class3 A2.1 and Class3 A2.2.

Full tree: make every branch available

A full-tree ViewModel expands every object matched by expressions in every nested branch. In the example, the ViewModel contains the root, both Class2 objects, all four Class3 objects, and all eight Class4 objects.

This shape lets a UI show all branches at the same time. For example, a tree can render Class2 A1 and Class2 A2, including their descendants, without first selecting either Class2 object.

Use a full tree when the rendering needs the whole hierarchy. A Turnkey tree view is a typical case: its nested UI repeats over the ViewModel collections that are already available to it.

Full-tree ViewModel structure

The ViewModel follows the model hierarchy:

Root: Class1
  Nesting: Class2 objects of the root
    Nesting: Class3 objects of each Class2
      Nesting: Class4 objects of each Class3

With the example data, this structure gives the UI access to all 15 objects.

Cursored tree: load the selected path

A cursored ViewModel uses one current object, or cursor, at each applicable collection level. The cursor determines which child branch is available below that level.

In a conventional master-detail screen:

  1. The Class1 root is fixed for the ViewModel instance.
  2. The Class2 list shows the two Class2 objects.
  3. The selected Class2 object is the Class2 cursor.
  4. The Class3 detail list shows only the Class3 objects below that selected Class2 object.
  5. If the user selects a Class3 object, its Class4 objects can be shown below it.

There can be one cursor per level. The root is supplied by the ViewModel root and is therefore already fixed. The lowest displayed level has no lower collection to select into, so it does not need a cursor for this purpose.

A cursor may be null. If no Class3 object has been selected, no Class4 branch is available. This is useful when Class4 objects are expensive to load or are irrelevant until the user chooses a Class3 object.

Cursored object count

If a Class2 object is selected but no Class3 object is selected, the example needs:

Loaded level Number of objects
Class1 root 1
Class2 collection 2
Class3 objects below the selected Class2 2
Class4 objects 0
Total 5

The full tree contains 15 objects for the same model data. The difference grows rapidly as you add nesting levels or increase the number of children at each level.

How this differs by client

The server can build either a full or sparse (cursored) ViewModel tree, but client behavior matters.

Client scenario Tree behavior described for the client Design implication
WCF client with an ECO space in memory Sparse trees are built. The client has the complete object space and can rebuild the ViewModel tree when selection changes. A cursor-based master-detail structure fits naturally.
Turnkey streaming client, including Angular web UI and WPF Turnkey client The server builds full trees and streams them to the client. A hierarchy expressed as ordinary nested collections makes all matching branches available to the client.

Do not confuse a UI that currently shows one branch with a ViewModel that contains one branch. A Turnkey UI can hide sibling branches, while the client still receives updates for those branches if the ViewModel was built as a full tree.

Use a cursored pattern in Turnkey

Turnkey ViewModels use the full-tree strategy when you model the hierarchy as nested collections. You can still design a cursor-based pattern to reduce what is loaded in advance by using the vCurrent_ variables at each level.

A vCurrent_ variable is the current selected object exposed by a ViewModel level. In this pattern, you use a current object from one level to determine the collection displayed at the next level, rather than nesting every child collection beneath every parent collection.

Reshape nested levels into root-level lists

Start with a hierarchy represented by three nested levels:

Root: Class1
  Class2 list
    Class3 list
      Class4 list

For a cursored Turnkey design, lift the cursor variables to the root and make the dependent lists use those current selections:

Root: Class1
  Class2 list
  Class3 list, determined by the current Class2
  Class4 list, determined by the current Class3

This changes the ViewModel from a deep collection tree to several lists at one level that depend on the current object of the preceding list. The resulting UI can still present a master-detail flow:

  1. Show the Class2 list.
  2. Let the user select a Class2 object.
  3. Show the Class3 list for that current Class2 object.
  4. Let the user select a Class3 object.
  5. Show the Class4 list for that current Class3 object.

The important result is that the Class3 list does not need to contain Class3 objects for every Class2 object, and the Class4 list does not need to contain Class4 objects for every Class3 object.

When to use each Turnkey pattern

Use the ordinary nested, full-tree structure when the UI needs multiple branches simultaneously. For example, a tree renderer needs child collections under every displayed node.

Use root-level dependent lists with vCurrent_ when the UI is master-detail and the user works through one selected path. For example, an editor with a Class2 grid, a Class3 grid for the selected Class2, and a Class4 grid for the selected Class3 should not load every Class4 collection merely to display one branch.

For the exact rules for vCurrent_, self, and selection behavior, see Documentation:How to use vCurrent and “self” correctly in viewmodels. For the general purpose and use of ViewModel variables, see Documentation:ViewModel variables.

Design checklist

Before adding nestings, answer these questions:

  1. Must the UI render more than one branch at the same time? If yes, use a full tree.
  2. Does each lower list depend on one selected parent item? If yes, use a cursored pattern with vCurrent_ variables.
  3. Can a selection be empty? Plan for the lower list to contain no objects until its parent cursor is set.
  4. How quickly does the number of objects multiply with each level? Count the expected objects at realistic data sizes, not only sample data.
  5. Does the UI need a custom hierarchy renderer? If yes, keep the ViewModel shape aligned with the collection names and levels expected by that renderer.

Use Documentation:QueryPlan when you need to inspect or reason about how data is retrieved. You can inspect and test the rendered Turnkey UI while developing through Documentation:TK Live View.

See also