Control guides

These guides explain how to choose, create, and connect the current XUI controls. They complement the public contracts, which define behavior and limits.

Choose a guide

Task Guide
Show text, accept a command, or edit one line Basic controls
Arrange content, scroll, or switch panes Layout and workspace
Choose an item, edit a number, or show progress Choices and values
Edit documents, collect form values, or open a dialog Documents and forms
Show large lists, tables, trees, or history Collections
Navigate pages, paths, and locations Navigation
Share commands, open menus, or customize window chrome Commands and windows
Show images, scenes, maps, media, or web content Images and native hosts

Use the examples

Each example has tabs in this order: .xui, C#, Rust, C++. The first tab shows the declarative path. Some controls require C# construction and the Content(...) bridge rather than a dedicated .xui node. Those tabs include the required setup. An unavailable API has an explicit support note instead of a substitute with different behavior.

Each example is independent. The examples do not form one concatenated application. Use the matching context below unless a guide supplies a complete application or additional source parameters.

A .xui tab contains a complete component. Save this example as GuidePanel.xui:

xui
namespace ControlExamples;

component GuidePanel {
    view {
        VStack(spacing: 8, padding: 16) {
            Text("Ready");
        }
    }
}

Create the component from an STA entry point:

using System;
using Xui;

internal static class Program
{
    [STAThread]
    private static int Main()
    {
        try
        {
            using var window = new Window("Control example", 800, 600);
            _ = new ControlExamples.GuidePanel(window);
            window.Run();
            return 0;
        }
        catch (Exception error)
        {
            Console.Error.WriteLine(error);
            return 1;
        }
    }
}

Replace component creation with the selected guide's constructor and any required C# setup. The component attaches its own Stack root by default. An element passed to Content(...) must belong to this window and must not already have a parent. The declarative guide describes project integration.

C# fragments use window, root, and anchor from this context. Put complete helper types at file scope.

using System;
using Xui;

internal static class Program
{
    [STAThread]
    private static int Main()
    {
        try
        {
            using var window = new Window("Control example", 800, 600);
            var root = window.Stack().Padding(16).Spacing(8);
            var anchor = window.Button("Open");
            root.Add(anchor);
            // Insert one C# guide fragment here.
            window.SetContent(root);
            window.Run();
            return 0;
        }
        catch (Exception error)
        {
            Console.Error.WriteLine(error);
            return 1;
        }
    }
}

The window disposes its owned controls after Run returns. The C# guide describes the managed reference, manifest, and native DLL.

Rust fragments use window, root, and anchor from this context. Question marks propagate native errors to the caller. Replace the body of example with the selected fragment. The three parameters are borrowed references.

use xui::*;

fn example(
    window: &Window,
    root: &Stack,
    anchor: &Button,
) -> std::result::Result<(), Box<dyn std::error::Error>> {
    let _ = (window, root, anchor);
    // Replace this body with one Rust guide fragment.
    Ok(())
}

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    let window = Window::new("Control example", 800., 600.)?;
    let root = window.stack(Axis::Vertical)?;
    root.padding(16.)?;
    root.spacing(8.)?;
    let anchor = window.button("Open")?;
    root.add(&anchor, 0.)?;
    example(&window, &root, &anchor)?;
    window.set_content(&root)?;
    window.run()?;
    Ok(())
}

Use weak control or Window captures for callbacks that the same native owner retains. The Rust guide explains ownership and callback errors.

C++ fragments use window, root, and anchor from this context:

#include "xui\application.hpp"

int run_example() {
    xui::Window window({L"Control example", {800, 600}});
    auto root = std::make_shared<xui::Stack>(xui::Axis::vertical);
    root->set_padding({16, 16, 16, 16});
    root->set_spacing(8);
    auto anchor = std::make_shared<xui::Button>(L"Open");
    root->add(anchor);
    // Insert one guide fragment here, with its additional headers.
    window.set_content(root);
    return xui::Application::run(window);
}

Put additional includes at file scope, not inside run_example. Each guide identifies any extra source parameter. The anchor already belongs to the root. Popup examples open only from its callback, after the window starts. All referenced local variables remain alive during Application::run.

For executable setup, use application composition. For binding setup and coverage, use the binding guide. For declarative components, use the .xui language guide.

Shared ownership and input rules

  • Each retained child has one layout parent. Null children, duplicate parents, and cycles are invalid.
  • The window retains its content. C++ controls use std::shared_ptr.
  • UI properties and callbacks belong to the creating UI thread.
  • Worker callbacks must deliver completion through a UI queue, such as C++ Window::post.
  • Callbacks must not outlive their captures. Strong references back to an owning control can create cycles.
  • Native editors retain Windows text input, IME, selection, clipboard, and undo behavior.
  • Window::focus requests application focus. Backend state setters do not replace this API.
  • Most property setters are silent. Semantic actions and collection selection have their documented event contracts.
  • Accessible names must describe the purpose, including icon-only buttons and nonvisual alternatives.

C# controls belong to a disposable Window. Rust controls retain their window owner and are not Send or Sync. Borrowed children do not support independent destruction. The binding ownership contract defines callback, snapshot, and request-token lifetimes.

Complete control catalog

The table separates public types, retained children, and presentations. Factory names refer to methods on the C# or Rust Window, unless the cell says otherwise. Availability does not imply identical properties across languages. The binding reference defines the exact surface.

Public control or API Guide section C# entry Rust entry
Element, Control base APIs Common properties Base wrappers, no factory Base wrappers, no factory
Label Label Label label
Button and behavior variants Button Button button
HyperlinkButton HyperlinkButton HyperlinkButton hyperlink_button
Toggle Toggle Toggle toggle
CheckBox CheckBox CheckBox check_box
InfoBadge InfoBadge InfoBadge info_badge
ToggleSwitch ToggleSwitch ToggleSwitch toggle_switch
ToggleButton ToggleButton ToggleButton toggle_button
TextInput and search variant TextInput TextInput text_input
NativeEditBridge backend boundary NativeEditBridge No factory No factory
Stack Stack Stack stack
ContentHost ContentHost CreateContentHost No typed wrapper
Grid Grid Grid grid
Wrap Wrap Wrap wrap
AdaptiveLayout AdaptiveLayout AdaptiveLayout adaptive_layout
ContentView ContentView No standalone factory No standalone factory
Reveal Reveal Reveal reveal
ScrollView ScrollView ScrollView scroll_view
SplitView SplitView SplitView split_view
PageView PageView PageView page_view
TabStrip TabStrip TabStrip tab_strip
RadioGroup RadioGroup RadioGroup radio_group
SelectorBar SelectorBar SelectorBar selector_bar
ChoiceList presentation ChoiceList Borrowed ComboBox.Choices Borrowed ComboBox::choices
ComboBox ComboBox ComboBox combo_box
NumericInput NumericInput NumericInput numeric_input
RangeInput RangeInput RangeInput range_input
Progress Progress Progress progress
ProgressRing ProgressRing ProgressRing progress_ring
Expander Expander Expander expander
SplitButton SplitButton SplitButton split_button
Popup Popup Popup popup
MultilineText MultilineText MultilineText multiline_text
RichText RichText RichText rich_text
PasswordInput PasswordInput PasswordInput password_input
DateTimePicker variants DateTimePicker DateTimePicker date_time_picker
InlineStatus InlineStatus InlineStatus inline_status
ColorPicker ColorPicker ColorPicker color_picker
ContentDialog facade ContentDialog ContentDialog content_dialog
FileList FileList FileList file_list
ItemsView variants ItemsView ItemsView items_view
TreeView TreeView TreeView tree_view
MillerColumns Miller columns MillerColumns miller_columns, construction only
MillerColumnList retained child Miller columns Borrowed MillerColumns.Column(index) as ItemsView No typed child accessor
DataGrid DataGrid DataGrid data_grid
HistoryChart HistoryChart HistoryChart history_chart
NavigationView NavigationView NavigationView navigation_view
NavigationList retained child NavigationList Retained NavigationView children Retained NavigationView children
Breadcrumb Breadcrumb Breadcrumb breadcrumb
NavigationPane NavigationPane NavigationPane navigation_pane
LocationPicker facade LocationPicker LocationPicker location_picker
ViewPicker facade ViewPicker ViewPicker view_picker
CommandMenu CommandMenu Borrowed CommandSurface.Menu, no factory Borrowed CommandSurface::menu, no factory
CommandBar CommandBar CommandBar command_bar
MenuBar MenuBar MenuBar menu_bar
CommandSurface facade CommandSurface CommandSurface command_surface
Native context menus and Shell services Native menus Binding contracts Binding contracts
CustomShellMenu facade CustomShellMenu No standalone factory No standalone factory
Window Window new Window Window::new
TitleBar TitleBar Window.Titlebar and child accessors Window::titlebar and child accessors
Tooltip API Tooltips Window.SetTooltipStyle Window::set_tooltip_style
Image Image Image image
VectorCanvas VectorCanvas VectorCanvas vector_canvas
MapView MapView MapView map_view
MediaPlayback MediaPlayback MediaPlayback media_playback
WebContent WebContent WebContent web_content
SwapChainPanel Swap chain panel Windows C++ only Windows C++ only

Control, DocumentText, VirtualCollection, and RuntimeHost provide shared behavior, not public standalone constructors. Element is constructible in C++, but it has no control behavior or style target. NativeEditBridge is a public Windows backend boundary, not a normal application-tree control. NavigationList has a private constructor and belongs to NavigationView. MillerColumnList has a private constructor and belongs to MillerColumns. ChoiceList is a RadioGroup presentation, not a C++ class. ContentDialog, CommandSurface, LocationPicker, and ViewPicker expose real Popup roots. Tooltip has no control constructor.

Models and services are not additional controls. Examples include ItemsSource, GridSource, TreeSource, CollectionSelection, CommandSet, CommandBindings, Commands, and ImageResources. ViewTask and SampleTask supply work delivery, not visual elements. The linked contracts describe those companion APIs.

Language and styling boundaries

The declarative language has 25 built-in nodes. Layout and composition use VStack, HStack, Grid, ScrollView, Popup, SplitView, Reveal, and Content. Basic controls use Text, Button, Toggle, ToggleSwitch, ToggleButton, CheckBox, HyperlinkButton, InfoBadge, and TextInput. Other forms are DataGrid, NavigationView, ItemsView, RangeInput, Progress, ProgressRing, SelectorBar, and MenuBar. Content mounts an existing element. It does not add a new native control class. Other bound controls require C# creation and explicit composition. The language guide defines that workflow.

The style catalog contains 46 targets and 223 target-part entries. These numbers do not count public constructors or declarative nodes. Some targets describe retained children or presentations. Other public facades use the Popup target instead of a facade target. ToggleSwitch, ToggleButton, and ProgressRing reuse the Toggle, Button, and Progress targets. CheckBox, HyperlinkButton, SelectorBar, InfoBadge, and MenuBar reuse Toggle, Button, ChoiceList, InlineStatus, and CommandBar targets, respectively.

Styles change supported properties and named parts. They do not replace retained children or native behavior. There are no shipped control templates, item templates, or implicit selectors. Shell HMENU appearance does not gain a style target. High contrast retains system colors and visible focus.

Use the styling contract for syntax, precedence, and diagnostics. Use the styling inventory for exact parts and native boundaries. Use retained child accessors for C# and Rust paths.