Repositories: Original (Onebeld) · Fork (ghudulf)
PleasantUI is a cross-platform UI theme and control library for Avalonia, inspired by Microsoft Fluent Design and the WinUI/UWP visual language. It completely re-styles every standard Avalonia control and adds a suite of custom controls, a multi-theme engine with custom theme support, a reactive localization system, and a custom window chrome — all AOT-compatible with no rd.xml required.
The project has been in active development since 2021, originally as part of the Regul and Regul Save Cleaner projects.
Every standard Avalonia control gets a full Fluent Design makeover — rounded corners, layered fill colors, smooth pointer-over and pressed transitions, and accent color integration:
| Control | Control | Control |
|---|---|---|
| Button (+ AppBar, Accent, Danger variants) | CheckBox | RadioButton |
| ToggleButton / ToggleSwitch | RepeatButton / ButtonSpinner | Slider |
| TextBox / AutoCompleteBox | NumericUpDown | ComboBox / DropDownButton |
| Calendar / CalendarDatePicker / TimePicker | DataGrid | ListBox / TreeView |
| Expander | TabControl / TabItem | ScrollBar / ScrollViewer |
| ProgressBar | Menu / ContextMenu | ToolTip |
| Carousel | Separator | NotificationCard |
Controls built from scratch that go beyond what Avalonia ships:
| Control | Description |
|---|---|
PleasantWindow |
Custom window chrome with a Fluent title bar, subtitle, custom icon/title content, optional blur, content-extends-into-titlebar, and macOS caption override |
NavigationView / NavigationViewItem |
Collapsible side navigation panel, similar to WinUI NavigationView |
PleasantTabView / PleasantTabItem |
Chromium-style tab strip with add/close buttons and scrollable tab bar |
ContentDialog |
Modal overlay dialog with bottom button panel and smooth scroll content area |
PleasantSnackbar |
Temporary non-intrusive notification bar |
ProgressRing |
Circular progress indicator — both determinate and indeterminate with animated arc |
OptionsDisplayItem |
Settings-style row with header, description, icon, action button slot, navigation chevron, and expandable content |
InformationBlock |
Compact pill-shaped label combining an icon and a value |
MarkedTextBox / MarkedNumericUpDown |
Input controls with inline label/unit markers |
RippleEffect |
Material-style ripple click feedback |
SmoothScrollViewer |
ScrollViewer with inertia gesture support |
PleasantMiniWindow |
Lightweight floating window |
- Built-in themes: Light, Dark, Mint, Strawberry, Ice, Sunny, Spruce, Cherry, Cave, Lunar
- System mode — follows the OS light/dark preference automatically
- Custom themes — create, edit, export, import, and persist your own color palettes via the built-in
ThemeEditorWindow - Accent color follows the OS accent or can be overridden per-user; light/dark variants and gradient pairs are generated automatically
- Settings are persisted to disk automatically on desktop; mobile apps can save manually
Localizersingleton backed by .NETResourceManager— add any number of.resxresource files{Localize Key}AXAML markup extension binds reactively — switching language updates every bound string instantly without reloading viewsLocalizer.TrDefault(key, fallback)for safe lookups that fall back to a raw string instead of an error messageLocalizationChangedevent for view models and code-behind to react to language switches
| Package | Description |
|---|---|
PleasantUI |
Core theme, all control styles, Pleasant controls, theme engine, localization |
PleasantUI.ToolKit |
MessageBox, ThemeEditorWindow, color picker utilities |
PleasantUI.MaterialIcons |
Material Design icon geometry library for use with PathIcon |
PleasantUI.DataGrid |
Fluent-styled DataGrid extension |
Detailed reference docs for each control are in the docs/ folder:
| Doc | Controls |
|---|---|
| PleasantWindow | PleasantWindow, IPleasantSplashScreen |
| PleasantMiniWindow | PleasantMiniWindow |
| NavigationView | NavigationView, NavigationViewItem |
| PleasantTabView | PleasantTabView, PleasantTabItem |
| ContentDialog | ContentDialog |
| MessageBox | MessageBox (ToolKit) |
| PleasantDialog | PleasantDialog (ToolKit) |
| PleasantSnackbar | PleasantSnackbar |
| ProgressRing | ProgressRing |
| OptionsDisplayItem | OptionsDisplayItem |
| InformationBlock | InformationBlock |
| DataGrid | PleasantUI.DataGrid package |
| Localization | Localizer, {Localize} markup extension |
| Theme Engine | PleasantTheme, custom themes, color tokens |
Package List (Avalonia 12)
Published on NuGet:
<PackageReference Include="PleasantUI" Version="5.1.0-alpha4.2" />
<PackageReference Include="PleasantUI.DataGrid" Version="5.1.0-alpha4.2" />
<PackageReference Include="PleasantUI.MaterialIcons" Version="5.1.0-alpha4.2" />
<PackageReference Include="PleasantUI.ToolKit" Version="5.1.0-alpha4.2" />In your App.axaml, add PleasantTheme to your styles:
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="YourApp.App">
<Application.Styles>
<PleasantTheme />
</Application.Styles>
</Application>Make sure AvaloniaXamlLoader.Load(this) is called in Initialize():
public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this); // required
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
{
DataContext = new MainWindowViewModel(),
};
}
base.OnFrameworkInitializationCompleted();
}
}Replace Window with PleasantWindow to get the custom Fluent title bar:
using PleasantUI.Controls;
public partial class MainWindow : PleasantWindow
{
public MainWindow() => InitializeComponent();
}<PleasantWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="YourApp.Views.MainWindow"
Title="Avalonia Application">
</PleasantWindow>Key PleasantWindow properties:
| Property | Type | Description |
|---|---|---|
TitleBarType |
Classic / ClassicExtended |
Title bar layout style |
ExtendsContentIntoTitleBar |
bool |
Lets content render behind the title bar |
Subtitle |
string |
Secondary text shown next to the title |
DisplayIcon |
object |
Custom icon content in the title bar |
DisplayTitle |
object |
Custom title content (e.g. a PathIcon) |
EnableBlur |
bool |
Acrylic/blur window background |
CaptionButtons |
enum | Which caption buttons to show |
LeftTitleBarContent |
object |
Content injected left of the title |
Register your .resx resource managers in your Application constructor:
public App()
{
Localizer.AddRes(new ResourceManager(typeof(Properties.Localizations.App)));
Localizer.ChangeLang("en");
}Use {Localize Key} in AXAML — updates live when the language changes:
<TextBlock Text="{Localize WelcomeMessage}" />
<Button Content="{Localize SaveButton}" />Switch language at runtime:
Localizer.ChangeLang("ru");Safe lookup with fallback in code-behind:
string title = Localizer.TrDefault("DialogTitle", "Confirm");<Button Content="Default" />
<Button Theme="{StaticResource AccentButtonTheme}" Content="Accent" />
<Button Theme="{StaticResource DangerButtonTheme}" Content="Danger" />
<Button Theme="{StaticResource AppBarButtonTheme}" Content="AppBar" /><!-- Navigation row -->
<OptionsDisplayItem Header="Account"
Description="Manage your account"
Icon="{x:Static MaterialIcons.AccountOutline}"
Navigates="True" />
<!-- Row with action control -->
<OptionsDisplayItem Header="Dark mode"
Icon="{x:Static MaterialIcons.WeatherNight}">
<OptionsDisplayItem.ActionButton>
<ToggleSwitch />
</OptionsDisplayItem.ActionButton>
</OptionsDisplayItem>
<!-- Expandable row -->
<OptionsDisplayItem Header="Advanced" Expands="True">
<OptionsDisplayItem.Content>
<StackPanel>
<CheckBox Content="Enable feature X" />
</StackPanel>
</OptionsDisplayItem.Content>
</OptionsDisplayItem>- AvaloniaUI
- Some controls inspired by PieroCastillo's Aura.UI
- ProgressRing by ymg2006
- Built with JetBrains Rider



