This guide will help you get up and running with Caliburn.Light as quickly as possible.
- Visual Studio 2026 or later
- .NET 10.0 SDK
- For WinUI: Windows App SDK
Choose the platform you want to target:
- Open Visual Studio
- Create a new WPF Application project targeting .NET 10.0
- Name it something like
MyApp
Install the following NuGet packages:
Install-Package Caliburn.Light.WPF
Install-Package Microsoft.Extensions.DependencyInjection
Delete MainWindow.xaml and MainWindow.xaml.cs - Caliburn.Light will handle window creation.
Create a new class called ShellViewModel.cs:
using Caliburn.Light;
using System.Windows.Input;
namespace MyApp;
public class ShellViewModel : BindableObject
{
private string _greeting = "Hello, Caliburn.Light!";
public ShellViewModel()
{
SayHelloCommand = DelegateCommandBuilder.NoParameter()
.OnExecute(() => Greeting = "Hello from the ViewModel!")
.Build();
}
public string Greeting
{
get => _greeting;
set => SetProperty(ref _greeting, value);
}
public ICommand SayHelloCommand { get; }
}Create a new Window called ShellView.xaml:
<Window x:Class="MyApp.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="My First Caliburn.Light App"
Height="200" Width="400">
<StackPanel Margin="20">
<TextBlock Text="{Binding Greeting}" FontSize="24" Margin="0,0,0,20"/>
<Button Content="Say Hello" Command="{Binding SayHelloCommand}" Padding="10,5"/>
</StackPanel>
</Window>The code-behind (ShellView.xaml.cs) should be minimal:
using System.Windows;
namespace MyApp;
public partial class ShellView : Window
{
public ShellView()
{
InitializeComponent();
}
}Update App.xaml.cs:
using Caliburn.Light;
using Caliburn.Light.WPF;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Windows;
namespace MyApp;
public partial class App : Application
{
private IServiceProvider? _serviceProvider;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var services = new ServiceCollection();
// Register Caliburn.Light services
services.AddSingleton<IWindowManager, WindowManager>();
services.AddSingleton<IEventAggregator, EventAggregator>();
services.AddSingleton<IViewModelLocator, ViewModelLocator>();
services.AddTransient(sp => sp.GetRequiredService<IOptions<ViewModelLocatorConfiguration>>().Value);
// Register view-viewmodel mapping
services.Configure<ViewModelLocatorConfiguration>(config =>
config.AddMapping<ShellView, ShellViewModel>());
// Register view and viewmodel
services.AddTransient<ShellView>();
services.AddTransient<ShellViewModel>();
_serviceProvider = services.BuildServiceProvider();
// Show the main window
_serviceProvider.GetRequiredService<IWindowManager>()
.ShowWindow(_serviceProvider.GetRequiredService<ShellViewModel>());
}
}Remove the StartupUri attribute from App.xaml:
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>Press F5 to run. You should see a window with "Hello, Caliburn.Light!" and a button that changes the text when clicked.
Congratulations! You've created your first Caliburn.Light application!
- Open Visual Studio
- Create a new Blank App, Packaged (WinUI 3 in Desktop) project
- Name it something like
MyApp
Install-Package Caliburn.Light.WinUI
Install-Package Microsoft.Extensions.DependencyInjection
Create ShellViewModel.cs:
using Caliburn.Light;
using System.Windows.Input;
namespace MyApp;
public class ShellViewModel : BindableObject
{
private string _greeting = "Hello, Caliburn.Light!";
public ShellViewModel()
{
SayHelloCommand = DelegateCommandBuilder.NoParameter()
.OnExecute(() => Greeting = "Hello from the ViewModel!")
.Build();
}
public string Greeting
{
get => _greeting;
set => SetProperty(ref _greeting, value);
}
public ICommand SayHelloCommand { get; }
}Create ShellView.xaml:
<Window x:Class="MyApp.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="My First Caliburn.Light App">
<StackPanel Margin="20" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="{x:Bind ViewModel.Greeting, Mode=OneWay}" FontSize="24" Margin="0,0,0,20"/>
<Button Content="Say Hello" Command="{x:Bind ViewModel.SayHelloCommand}" Padding="10,5"/>
</StackPanel>
</Window>Code-behind (ShellView.xaml.cs):
using Microsoft.UI.Xaml;
namespace MyApp;
public sealed partial class ShellView : Window
{
public ShellView()
{
InitializeComponent();
}
public ShellViewModel? ViewModel => Content?.DataContext as ShellViewModel;
}Update App.xaml.cs:
using Caliburn.Light;
using Caliburn.Light.WinUI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.UI.Xaml;
namespace MyApp;
public partial class App : Application
{
private IServiceProvider? _serviceProvider;
public App()
{
InitializeComponent();
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
var services = new ServiceCollection();
// Register Caliburn.Light services
services.AddSingleton<IWindowManager, WindowManager>();
services.AddSingleton<IEventAggregator, EventAggregator>();
services.AddSingleton<IViewModelLocator, ViewModelLocator>();
services.AddTransient(sp => sp.GetRequiredService<IOptions<ViewModelLocatorConfiguration>>().Value);
// Register view-viewmodel mapping
services.Configure<ViewModelLocatorConfiguration>(config =>
config.AddMapping<ShellView, ShellViewModel>());
// Register view and viewmodel
services.AddTransient<ShellView>();
services.AddTransient<ShellViewModel>();
_serviceProvider = services.BuildServiceProvider();
_serviceProvider.GetRequiredService<IWindowManager>()
.ShowWindow(_serviceProvider.GetRequiredService<ShellViewModel>());
}
}- Install the Avalonia templates:
dotnet new install Avalonia.Templates - Create a new project:
dotnet new avalonia.app -o MyApp
dotnet add package Caliburn.Light.Avalonia
dotnet add package Microsoft.Extensions.DependencyInjection
Create ShellViewModel.cs:
using Caliburn.Light;
using System.Windows.Input;
namespace MyApp;
public class ShellViewModel : BindableObject
{
private string _greeting = "Hello, Caliburn.Light!";
public ShellViewModel()
{
SayHelloCommand = DelegateCommandBuilder.NoParameter()
.OnExecute(() => Greeting = "Hello from the ViewModel!")
.Build();
}
public string Greeting
{
get => _greeting;
set => SetProperty(ref _greeting, value);
}
public ICommand SayHelloCommand { get; }
}Create ShellView.axaml:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.ShellView"
Title="My First Caliburn.Light App"
Width="400" Height="200">
<StackPanel Margin="20" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="{Binding Greeting}" FontSize="24" Margin="0,0,0,20"/>
<Button Content="Say Hello" Command="{Binding SayHelloCommand}" Padding="10,5"/>
</StackPanel>
</Window>Update App.axaml.cs:
using Avalonia;
using Avalonia.Markup.Xaml;
using Caliburn.Light;
using Caliburn.Light.Avalonia;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace MyApp;
public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
var services = new ServiceCollection();
// Register Caliburn.Light services
services.AddSingleton<IWindowManager, WindowManager>();
services.AddSingleton<IEventAggregator, EventAggregator>();
services.AddSingleton<IViewModelLocator, ViewModelLocator>();
services.AddTransient(sp => sp.GetRequiredService<IOptions<ViewModelLocatorConfiguration>>().Value);
// Register view-viewmodel mapping
services.Configure<ViewModelLocatorConfiguration>(config =>
config.AddMapping<ShellView, ShellViewModel>());
// Register view and viewmodel
services.AddTransient<ShellView>();
services.AddTransient<ShellViewModel>();
var serviceProvider = services.BuildServiceProvider();
serviceProvider.GetRequiredService<IWindowManager>()
.ShowWindow(serviceProvider.GetRequiredService<ShellViewModel>());
base.OnFrameworkInitializationCompleted();
}
}Now that you have a working application, explore these topics:
- Commands - Learn about the command infrastructure
- Screens, Conductors and Composition - Build complex view hierarchies
- Validation - Add validation to your view models
- The Event Aggregator - Implement loosely-coupled communication
- The Window Manager - Show windows and dialogs
Check out the complete sample applications in the repository: