Skill v1.0.0
currentAutomated scan100/100version: "1.0.0" name: gum-forms-controls description: Gum Forms controls (Button, Label, TextBox, CheckBox, ListBox, StackPanel…) vs raw visuals, and the state/category styling system. Triggers: adding a button/textbox/list, WPF-style properties not working, IsVisible, styling a control, DefaultVisuals.
Gum Forms Controls
Forms controls are interactive UI classes whose names mirror WPF (Button, CheckBox, TextBox, …), but they are laid out and rendered by Gum, not WPF. Reach for a Forms control for anything the player clicks, types in, or scrolls. For non-interactive HUD/decoration, use raw visuals instead (see below). Docs: <https://docs.flatredball.com/gum/code/controls>.
Common controls
Button, ToggleButton, RadioButton, CheckBox, Label, TextBox, PasswordBox, ComboBox, ListBox, Slider, ScrollBar, ScrollViewer, StackPanel, Panel, Menu, Window, Splitter.
Using a control in code
using Gum.Forms.Controls;var button = new Button();button.Text = "Play";button.AddToRoot(); // adds it to the screenbutton.Click += (_, _) => StartGame();
Text-bearing controls share this shape — new Label(), new TextBox(), etc. all expose .Text. Set position/size with Gum's unit system (see gum-layout), not WPF layout.
Composing controls (parenting in code)
AddToRoot() attaches a control to the screen. To nest one control inside another — buttons inside a panel, anything inside a container — call AddChild on the parent. There is no .Children.Add(...) on a Forms control.
var menu = new StackPanel(); // stacks its children; vertical by defaultmenu.Spacing = 8; // gap between children (StackPanel.Spacing)menu.AddToRoot();var play = new Button { Text = "Play" };var quit = new Button { Text = "Quit" };menu.AddChild(play); // parents the control under the panelmenu.AddChild(quit);
AddChild(child) sets the child's visual parent; the parent's layout then positions it — a StackPanel stacks them, and any container with ChildrenLayout set arranges them. RemoveChild undoes it. StackPanel defaults to Orientation.Vertical; set Orientation = Orientation.Horizontal for a row.
Forms vs raw visuals
| Need | Use | |
|---|---|---|
| Player interaction (click/type/scroll) | A Forms control | |
| Static text | TextRuntime | |
| Solid color block | ColoredRectangleRuntime | |
| Image | SpriteRuntime | |
| Scalable panel/border | NineSliceRuntime | |
| Plain layout container | ContainerRuntime |
Raw visuals: <https://docs.flatredball.com/gum/code/standard-visuals>.
Landmine: WPF conventions do not carry over
The names match WPF; the property model does not. On a Forms control:
- No
Margin,Padding, or WPF-styleHorizontalAlignment/VerticalAlignment.
Position and size come from Gum units (X, XUnits, Width, WidthUnits, …).
- No
Background,Foreground, orBorderBrush. Color and appearance come
from states (below), not brush properties.
- No
Visibilityenum. Use theIsVisiblebool. - No WPF
Autosizing. AButtonwithWidth = 128is 128 px wide
regardless of its text unless WidthUnits = RelativeToChildren. See gum-layout.
For a fuller WPF-to-Gum translation: <https://docs.flatredball.com/gum/code/about/for-wpf-users>.
The state / category system (how styling works)
Appearance is driven by named states grouped into a category on the control's visual, not by per-property setters. A Button's visual, for example, carries a category with Enabled, Highlighted, Pushed, Focused, and Disabled states; the control switches between them automatically as the player interacts. Each state sets a batch of variables (colors, sizes) at once.
To recognize this in code: applying a state name changes the look; the control does this for you on hover/press/focus. To customize appearance you edit the states (in the tool, or via the styling APIs) or swap in a different visual — you do not look for a Color property on the control. Don't panic when you see categories and states; they are Gum's equivalent of a style sheet. How to restyle controls: gum-styling. A complete pre-built look: gum-theming.
Default visuals
A newly-constructed control (new Button()) gets a built-in default visual so it renders without any project. Replacing or restyling that visual is the styling story above. If a control looks unstyled or blank, its visual — not the control class — is what to inspect.