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
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:
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::focusrequests 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.
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.