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:
- 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>- Avalonia
- Some controls inspired by PieroCastillo's Aura.UI
- ProgressRing by ymg2006
- Built with JetBrains Rider














