Gum Forms Controls
SkillDev toolsGum 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.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Gum Forms Controls skill
What this skill tells your AI
The instructions your AI receives, as published by vchelaru/gum in gum-skills/gum-forms-controls/SKILL.md and read by ahel’s review.
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 screen
button.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 default
menu.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 panel
menu.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 unlessWidthUnits = 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. Styling
guide: https://docs.flatredball.com/gum/code/styling.
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.
Signals
- GitHub stars
- 620
- Forks
- 80
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
gum-forms-controls- Source
- github.com/vchelaru/gum