Quick Start
This guide walks you through creating your first Awen story from scratch.
1. Create Your Projects
You need two projects: a control library (your Avalonia UI controls) and a stories assembly (the stories that showcase them).
# Control library
dotnet new classlib -n MyControls
cd MyControls
dotnet add package Avalonia
dotnet add package Avalonia.Themes.Fluent
cd ..
# Stories assembly
dotnet new classlib -n MyControls.Stories
cd MyControls.Stories
dotnet add reference ../MyControls/MyControls.csproj
dotnet add package Awen.Sdk
dotnet add package Avalonia
cd ..
2. Register Your Story Assembly
Create an AssemblyInfo.cs in your stories project:
using Awen.Sdk;
[assembly: AwenStoryAssembly("My Controls")]
The "My Controls" string becomes the top-level sidebar node in Awen.
3. Write a Story
Stories follow a 5-file convention inside a folder structure that mirrors the sidebar hierarchy:
MyControls.Stories/
Buttons/
MyButton/
Default/
Story.cs
Control.axaml
Control.axaml.cs
Properties.axaml
Properties.axaml.cs
Story.cs — The ViewModel
The story class implements IStory<TControl, TStoryProperties> and acts as the shared DataContext for both the preview and properties panel:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Avalonia.Controls;
using Awen.Sdk;
namespace MyControls.Stories.Buttons.MyButton.Default;
public sealed class Story : IStory<UserControl, UserControl>, INotifyPropertyChanged
{
private string _label = "Click Me";
public event PropertyChangedEventHandler? PropertyChanged;
string IStory<UserControl, UserControl>.Name => "Default";
string IStory<UserControl, UserControl>.Group => "Atoms/Buttons";
int IStory<UserControl, UserControl>.Order => 0;
string IStory<UserControl, UserControl>.Description =>
"A basic button with a configurable label.";
public string Label
{
get => _label;
set { _label = value; OnPropertyChanged(); }
}
UserControl IStory<UserControl, UserControl>.CreateControl() => new Control();
UserControl IStory<UserControl, UserControl>.CreateProperties() => new Properties();
private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
Control.axaml — The Preview
This wraps your actual control and binds its properties to the Story:
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:MyControls"
xmlns:local="using:MyControls.Stories.Buttons.MyButton.Default"
x:Class="MyControls.Stories.Buttons.MyButton.Default.Control"
x:DataType="local:Story">
<controls:MyButton Content="{Binding Label}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</UserControl>
Properties.axaml — The Editor Panel
Provides interactive editors for the story's properties:
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyControls.Stories.Buttons.MyButton.Default"
x:Class="MyControls.Stories.Buttons.MyButton.Default.Properties"
x:DataType="local:Story">
<StackPanel Spacing="12" Margin="8">
<StackPanel Spacing="4">
<TextBlock Text="Label" FontWeight="SemiBold" />
<TextBox Text="{Binding Label}" />
</StackPanel>
</StackPanel>
</UserControl>
Code-Behind Files
Both Control.axaml.cs and Properties.axaml.cs are minimal:
using Avalonia.Controls;
namespace MyControls.Stories.Buttons.MyButton.Default;
public sealed partial class Control : UserControl
{
public Control() { InitializeComponent(); }
}
4. Build and Run
# Build your stories
dotnet build MyControls.Stories
# Launch Awen pointing at the stories output
Awen --dir MyControls.Stories/bin/Debug/net10.0/
Your control should appear in the sidebar under My Controls > Atoms > Buttons > Default.