The ScrollViewer control is a general-purpose control which can be used to display a scrollable area. The ScrollViewer exposes a control called InnerPanel which is the host for all content within the ScrollViewer. The InnerPanel is a Gum GraphialUiElement so its sizing and positioning rules are flexible and can be modified either in code or Gum.

Layout Requirements

The ScrollViewer control requires:

  • An object named VerticalScrollBarInstance which implements ScrollBarBehavior (is a ScrollBar)
  • An object named InnerPanelInstance of any type (typically a Container)
  • An object named ClipContainerInstance of any type (typically a Container with ClipsChildren set to true)

ClipContainerInstance Recommendations

The clip container is a container which will hold the InnerPanelInstance. The hierarchy of controls should be:

  • ScrollViewerComponent
    • VerticalScrollBarInstance
    • ClipContainerInstance
      • InnerPanelInstance
        • Contents of the ScrollViewer – added at runtime through code

This hierarchy allows each control to serve a separate function. The clip container’s purpose is to clip the drawing of all contained objects. The clip container prevents the inner panel (and all controls within the inner panel) from overlapping the vertical scroll bar and from spilling out of the scroll viewer.

The clip container should be of standard type Container because this control is typically used for clipping children.

The clip container should have its ClipsChildren variable set to true. For information on this property, see the Gum documentation on ClipsChildren:

The clip container will typically fill the most of the scroll viewer component, leaving room for the vertical scroll bar and any desired border. This can be accomplished by setting WidthUnits and HeightUnits to RelativeToContainer.

ScrollBarVisibility Category

ScrollViewer instances support hiding or showing the VerticalScrollBarInstance. This can impact the horizontal size of the ClipContainerInstance. In the case of a hidden VerticalScrollBarInstance, the ClipContainerInstance should extend to occupy space that would otherwise be used by the VerticalScrollBarInstance.

To respond to the VerticalScrollBarInstance being hidden and shown, the ScrollViewer Gum object should have a state category titled ScrollBarVisibility with two states:

  1. NoScrollBar
  2. VerticalScrollVisible

These two states should adjust the visibility of the VerticalScrollBarInstance and the width of the ClipContainerInstance as shown in the following diagram:

Keep in mind that this category applies to any control which inherits from ScrollBar, such as ListBox.

InnerPanelInstance Recommendations

The inner panel is used to provide the following behavior:

  • Scrolls all contents in response to the vertical scroll bar events
  • Provides size information to the vertical scroll bar to resize the thumb (see more information below)
  • Provides a common parent to all custom content for scrolling

Currently the ScrollViewer control only supports vertical scrolling, so the inner panel should be configured to grow and shrink only on the Y axis. This can be accomplished by setting the following values on the InnerPanelInstance:

  • X = 0
  • X Units = PixelsFromLeft
  • Y = 0
  • Y Units = PixelsFromTop
  • Width = 0
  • Width Units = RelativeToContainer (makes the panel stretch horizontally to the width of the ClipContainerInstance)
  • Height = 0
  • Height Units = RelativeToChildren (makes the panel initially have no height, but makes it stretch vertically according to its contents)

Setting HeightUnits to RelativeToChildren results in the inner panel enables automatic resizing according to the inner panel’s children (which are added at runtime).

As additional controls are added to inner panel, it will expand vertically. Controls which fall outside of the clip container will not be rendered. The following diagram shows this, but has controls outside of the clip container dimmed for illustrative purposes:

InnerPanelInstance and Children Layout

The inner panel can be used to hold controls which are positioned in absolute pixel values or which are automatically stacked (such as a list box).

If the controls within the inner panel are to be positioned in absolute terms, the Children Layout value should be set to Regular.

If the controls within the inner panel are to be stacked automatically, the inner panel Children Layout value should be set to TopToBottomStack.

Manually Sizing ScrollViewer

When working with a ScrollViewer we need to consider two sizes:

  1. Width and Height of the ScrollViewer itself, which can be explicitly in code or which can be set on the Gum runtime object in the Gum tool
  2. The InnerPanel width and height, which also can be explicitly set in code or which can be set on the Gum runtime object in the Gum tool


The following code shows how a manually sized ScrollViewer will behave:

var scrollViewer = TutorialScreenGum
    .FormsControlAsObject as ScrollViewer;

scrollViewer.Visual.WidthUnits = 
scrollViewer.Visual.Width = 200;

scrollViewer.Visual.HeightUnits =
scrollViewer.Visual.Height = 400;

scrollViewer.InnerPanel.WidthUnits = 
scrollViewer.InnerPanel.Width = 70;

scrollViewer.InnerPanel.HeightUnits =
// Make the inner panel really tall:
scrollViewer.InnerPanel.Height = 1000;

When viewing the code above, keep in mind:

  • At the time of this writing the ScrollViewer object only supports scrolling vertically (up and down).
  • We set the scrollViewer.Visual’s WidthUnits, Width, HeightUnits, and Height for the sake of making a clear example. This is not necessary (and often not desirable) in a real world example where layout is controlled by the Gum tool.

The code above adjusts the ScrollViewer such that the view displays 40% (400 / 1000) of the available height of the InnerPanel. The scroll bar can be used to to scroll through the container.

Adding to InnerPanel

Controls can be added to the InnerPanel in code. The following code shows how to create and add 20 ColoredRectangle of random color to an Inner Panel.

var random = FlatRedBallServices.Random;

// It's common to have the InnerPanel
// automatically stack its children, so we'll
// set it to not stack. This isn't necessary
// If you've set the ChildrenLayout in Gum:
scrollViewer.InnerPanel.ChildrenLayout = Gum.Managers.ChildrenLayout.Regular;

for(int i = 0; i < 20; i++)
    var rect = new GumRuntimes.ColoredRectangleRuntime();
    rect.Width = 40;
    rect.Height = 40;

    rect.Red = random.Next(255);
    rect.Green = random.Next(255);
    rect.Blue = random.Next(255);

    rect.X = random.Next(50);
    rect.Y = i * 50;

    rect.Parent = scrollViewer.InnerPanel;

The code above will produce the following ScrollViewer:

Expanding Stacking ScrollViewer

ScrollViewers are often used to display a stack of UI. This can be accomplished by modifying the following InnerPanel variables:

  • Height = 0 (or a small positive number for a border)
  • HeightUnits = RelativeToChildren
  • ChildrenLayout = TopToBottomStack

This can all be done in Gum or code. The following code example shows how to do this all in code:

scrollViewer = TutorialScreenGum
    .FormsControlAsObject as ScrollViewer;

// Setting Height, HeightUnits, and ChildrenLayout can be done in Gum or code:
scrollViewer.InnerPanel.Height = 0;
scrollViewer.InnerPanel.HeightUnits = Gum.DataTypes.DimensionUnitType.RelativeToChildren;
scrollViewer.InnerPanel.ChildrenLayout = Gum.Managers.ChildrenLayout.TopToBottomStack;

for(int i = 0; i < 10; i++)
    var buttonRuntime = new GumRuntimes.ButtonRuntime();
    buttonRuntime.Text = $"Button number {i}";
    buttonRuntime.Parent = scrollViewer.InnerPanel;