gum-tool-dialogs
$
npx mdskill add vchelaru/Gum/gum-tool-dialogsResolve dialog system choices and implement custom popup windows.
- Handles MVVM dialog creation, scrolling, and layout configuration.
- Integrates with DialogService, DialogWindow, and XAML view templates.
- Uses attached properties and view model naming conventions for resolution.
- Delivers interactive popups with custom buttons and scroll behaviors.
SKILL.md
.github/skills/gum-tool-dialogsView on GitHub ↗
--- name: gum-tool-dialogs description: Reference guide for Gum's dialog/popup systems. Load this when working on dialog windows, DialogService, DialogWindow, DeleteOptionsWindow, dialog scrolling, dialog layout, or adding new dialog types. --- # Gum Dialog Systems Reference ## Two Separate Systems Gum has **two independent dialog systems**. Knowing which one is involved is critical before making changes. ### 1. DialogService System (MVVM, most dialogs) Used by: message popups, yes/no confirmations, text input, choice selection, plugin management, import dialogs. **Flow**: `DialogService` creates a `DialogWindow`, sets its `DataContext` to a view model. The `Dialog` control inside uses a `DialogTemplateSelector` to resolve the view model type to a `UserControl` view. After the view loads, `Dialog.OnContentChanged` binds attached properties from the view up to the `Dialog` control via deferred dispatch (`DispatcherPriority.Loaded`). **Key attached properties on views** (set in XAML on the UserControl): - `Dialog.DialogTitle` — window title - `Dialog.Actions` — custom button area (replaces default OK/Cancel) - `Dialog.AuxiliaryActions` — extra buttons on the left side (e.g. Browse) - `Dialog.ScrollContent` — `true` (default) enables outer ScrollViewer; `false` disables it so the view can manage its own scrolling (used by ImportFromGumxView) **View resolution**: `DialogViewResolver` maps view model types to views by naming convention (`FooViewModel` -> `FooView`) or by `[Dialog(typeof(VM))]` attribute. Scans assemblies lazily and caches results. **Window sizing**: `DialogWindow` starts with `SizeToContent="WidthAndHeight"`. After content loads, `Dialog.OnContentChanged` switches to `SizeToContent.Manual` and clears the view's fixed Width/Height (sets to NaN), allowing the window to be resizable. `DialogService.CreateDialogWindow` sets `MaxHeight` to the owner window's `ActualHeight`. ### 2. DeleteOptionsWindow (standalone, code-behind) Used by: delete confirmation only (`DeleteLogic.ShowDeleteDialog`). **Why it exists separately**: The delete dialog needs runtime UI composition — plugins inject checkboxes and options into a `StackPanel` (e.g., "Delete associated files?", "Remove child instances?"). This cannot be done through the MVVM template system. **Flow**: `DeleteLogic` creates a `DeleteOptionsWindow` directly, sets `Message` and `Title` properties, calls `PluginManager.ShowDeleteDialog()` (which lets plugins add controls to `MainStackPanel`), then calls `ShowDialog()`. **Not managed by DialogService** — no view model, no template selection, no attached property binding. Changes to `DialogWindow.xaml` or `Dialog.cs` have **zero effect** on this window. ## Key Files | File | System | Purpose | |------|--------|---------| | `Gum/Services/Dialogs/DialogService.cs` | MVVM | Creates and shows DialogWindow instances | | `Gum/Services/Dialogs/DialogWindow.xaml` | MVVM | Window chrome, layout template with ScrollViewer + button footer | | `Gum/Services/Dialogs/Dialog.cs` | MVVM | ContentControl with attached properties and template selector | | `Gum/Services/Dialogs/DialogViewResolver.cs` | MVVM | Maps view model types to view types | | `Gum/Services/Dialogs/DialogViewModel.cs` | MVVM | Base class with affirm/negative commands and RequestClose event | | `Gum/Gui/Windows/DeleteOptionsWindow.xaml` | Standalone | Delete confirmation window layout | | `Gum/Gui/Windows/DeleteOptionsWindow.xaml.cs` | Standalone | Code-behind with plugin-accessible StackPanel | | `Gum/Managers/DeleteLogic.cs` | Standalone | Creates and shows DeleteOptionsWindow (line ~227) | ## Common Pitfalls **Wrong system**: The most common mistake is modifying `DialogWindow.xaml` or `Dialog.cs` expecting it to affect the delete dialog. Always verify which system shows the dialog you're fixing. **ScrollViewer behavior**: The `Dialog` template wraps content in a ScrollViewer. With `Auto` scrolling, child controls get infinite available height during WPF measure — so internal scroll viewers (like a TreeView) won't scroll. Set `Dialog.ScrollContent="False"` on views that need bounded height for internal scrolling. **Deferred binding**: `Dialog.OnContentChanged` binds attached properties at `DispatcherPriority.Loaded`, not immediately. Code that reads these values before the dispatch fires will see defaults.