Tutorial 1: Hello Window

Difficulty: Beginner | Prerequisites: .NET 8+ installed | Estimated reading time: ~5 minutes

Tutorials | Next → Tutorial 2: Live Dashboard


What you'll build: A single window with a title, a label, and a Quit button — the minimal complete SharpConsoleUI application.

Most terminal programs use immediate-mode output: you call Console.Write, the characters land on screen, and the terminal holds them — there is no concept of redrawing or responding to resize. SharpConsoleUI uses a retained-mode model instead: you declare a tree of controls, and the framework owns rendering, redraws, and input routing for the lifetime of the application. The result is that redraws, focus management, and scrolling are handled automatically — your code describes what the UI should look like, not when to paint each pixel.

Step 1: Create the project

Create a new console project and add the SharpConsoleUI package:

dotnet new console -n HelloWindow
cd HelloWindow
dotnet add package SharpConsoleUI

Open Program.cs — replace its contents as we go through each step.

Step 2: Create the window system

The ConsoleWindowSystem owns all windows; NetConsoleDriver abstracts terminal output and enables headless testing.

using SharpConsoleUI;
using SharpConsoleUI.Drivers;

var driver = new NetConsoleDriver(RenderMode.Buffer);
var windowSystem = new ConsoleWindowSystem(driver);

Nothing visible yet — the system is set up but no windows have been added.

Step 3: Create a window

WindowBuilder gives you a fluent API for configuring a window before it's added to the system.

using SharpConsoleUI.Builders;

var window = new WindowBuilder(windowSystem)
    .WithTitle("Hello World")
    .WithSize(50, 12)
    .Centered()
    .Build();

Run dotnet run after adding windowSystem.AddWindow(window); windowSystem.Run(); (covered in Step 6) — you'll see a bordered window centred in the terminal.

Step 4: Add a label

MarkupControl displays styled text using the [tag]text[/] markup syntax — controls stack vertically inside the window by default.

using SharpConsoleUI.Controls;

window.AddControl(Controls.Markup()
    .AddLine("[bold cyan]Hello, SharpConsoleUI![/]")
    .Build());

The label appears on the first line of the window's content area.

See Markup Syntax for the full tag reference.

Step 5: Add a Quit button

ButtonControl is focusable and interactive — pressing Enter or clicking it fires the Click event.

window.AddControl(Controls.Button("Quit")
    .OnClick((sender, e, win) =>
    {
        windowSystem.Shutdown();
    })
    .Build());

Tab to the button and press Enter (or click it) to exit. The win parameter in OnClick lets you call FindControl<T>() to reach other controls in the same window.

Step 6: Add the window and run

AddWindow registers the window with the system; Run starts the render and input loop and blocks until Shutdown() is called.

windowSystem.AddWindow(window);
windowSystem.Run();

The full app is now running. Press Tab to switch focus, Enter to click the button.

Complete Program.cs

using SharpConsoleUI;
using SharpConsoleUI.Builders;
using SharpConsoleUI.Controls;
using SharpConsoleUI.Drivers;

var driver = new NetConsoleDriver(RenderMode.Buffer);
var windowSystem = new ConsoleWindowSystem(driver);

var window = new WindowBuilder(windowSystem)
    .WithTitle("Hello World")
    .WithSize(50, 12)
    .Centered()
    .Build();

window.AddControl(Controls.Markup()
    .AddLine("[bold cyan]Hello, SharpConsoleUI![/]")
    .Build());

window.AddControl(Controls.Button("Quit")
    .OnClick((sender, e, win) => windowSystem.Shutdown())
    .Build());

windowSystem.AddWindow(window);
windowSystem.Run();

What you learned

  • Window system and driver — ConsoleWindowSystem + NetConsoleDriver
  • WindowBuilder — fluent API for size, title, position
  • window.AddControl() — controls stack vertically by default
  • MarkupControl — styled text with [bold], [cyan], etc.
  • ButtonControl with OnClick handler
  • windowSystem.Shutdown() — stops the run loop
  • windowSystem.AddWindow() + windowSystem.Run() — the startup sequence

Next → Tutorial 2: Live Dashboard — async window threads, live-updating panels, and a graph control.