AutoSettingUI is a .NET library that automatically generates settings UI panels from plain C# objects decorated with attributes. Annotate a class, hand it to the control, and a fully functional settings form is rendered — no manual UI wiring required.
- 🎨 Multi-framework — Avalonia, Ursa (Avalonia), and WPF panels included
- ✨ Attribute-driven — Decorate properties with attributes to customize rendering
- ⚡ AOT-compatible — Incremental Roslyn Source Generator enables full Native AOT and trimming support
- 🔄 MVVM Support — Works with CommunityToolkit.Mvvm
[ObservableProperty] - 🌐 i18n Support — Built-in localization service with dynamic language switching powered by DynamicLocalization
- 🔌 Extensible — Inject custom providers and accessors
- 🧭 Built-in navigation — Sidebar tree navigation to sections
- 🎯 Extended Controls — ColorPicker, DatePicker, TimePicker, NumericUpDown, and more
<!-- Avalonia -->
<PackageReference Include="AutoSettingUI.Avalonia" />
<!-- Ursa (Avalonia with Ursa theme) -->
<PackageReference Include="AutoSettingUI.Ursa" />
<!-- WPF -->
<PackageReference Include="AutoSettingUI.WPF" />
<!-- AOT Support (Optional) -->
<PackageReference Include="AutoSettingUI.Generator" />Target Frameworks: net8.0; net9.0; net10.0 (WPF: net8.0-windows; net9.0-windows; net10.0-windows)
Avalonia: AutoSettingUI.Avalonia requires Avalonia >= 11.0.0. AutoSettingUI.Ursa requires Avalonia >= 11.1.1 (Ursa dependency).
⚠️ Important: For Avalonia and Ursa projects, add the theme style reference toApp.axaml.
Avalonia:
<Application.Styles>
<FluentTheme />
<StyleInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml"/>
<StyleInclude Source="avares://AutoSettingUI.Avalonia/Themes/Generic.axaml"/>
</Application.Styles>Ursa:
<Application.Styles>
<u-semi:SemiTheme Locale="zh-CN" />
<StyleInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml"/>
<StyleInclude Source="avares://AutoSettingUI.Ursa/Themes/Generic.axaml"/>
</Application.Styles>using AutoSettingUI.Core.Attributes;
using AutoSettingUI.Avalonia.Attributes; // or AutoSettingUI.Ursa.Attributes
[SettingUI]
[MainHeader("Application Settings")]
public class AppSettings
{
[Title("Application Name")]
public string AppName { get; set; } = "My Application";
[Title("Volume")]
[Range(0, 100)]
public int Volume { get; set; } = 50;
[Title("Enable Logging")]
[CheckBox]
public bool EnableLogging { get; set; }
[Title("Font Size")]
[NumericUpDown(Minimum = 8, Maximum = 32)]
public int FontSize { get; set; } = 14;
}using CommunityToolkit.Mvvm.ComponentModel;
[SettingUI]
[MainHeader("Application Settings")]
public partial class ApplicationSettings : ObservableObject
{
[Title("Application Name")]
[ObservableProperty]
private string _appName = "My Application";
[Title("Enable Logging")]
[ObservableProperty]
private bool _enableLogging;
}Avalonia:
<Window xmlns:auto="clr-namespace:AutoSettingUI.Avalonia.Controls;assembly=AutoSettingUI.Avalonia">
<auto:AvaloniaAutoSettingPanel Targets="{Binding Targets}" />
</Window>Ursa:
<Window xmlns:ursa="clr-namespace:AutoSettingUI.Ursa.Controls;assembly=AutoSettingUI.Ursa">
<ursa:UrsaAutoSettingPanel Targets="{Binding Targets}" />
</Window>WPF:
<Window xmlns:auto="clr-namespace:AutoSettingUI.WPF.Controls;assembly=AutoSettingUI.WPF">
<auto:WpfAutoSettingPanel Targets="{Binding Targets}" />
</Window>ViewModel:
public class MainViewModel
{
public IEnumerable<object> Targets { get; } = new object[] { new AppSettings() };
}For Native AOT or trimming, the generator is picked up automatically. To force registration:
using AutoSettingUI.Core.Registry;
using AutoSettingUI.Generated;
AotSettingRegistry.Provider = new GeneratedSettingProvider();
AotSettingRegistry.Accessor = AotSettingRegistry.Provider;AutoSettingUI supports dynamic language switching powered by DynamicLocalization.
Set UseResourceKey = true on title attributes:
[SettingUI]
[MainHeader("Settings.Application", UseResourceKey = true)]
public class ApplicationSettings
{
[Title("Settings.AppName", UseResourceKey = true)]
public string AppName { get; set; } = "My Application";
[Title("Settings.EnableLogging", UseResourceKey = true)]
public bool EnableLogging { get; set; }
}1. Create resource files (.resx):
Strings.resx(default/English)Strings.zh-CN.resx(Chinese Simplified)
2. Create a resource accessor class:
namespace YourApp.Resources;
public static class Strings
{
public static System.Resources.ResourceManager ResourceManager { get; }
= new System.Resources.ResourceManager(
"YourApp.Resources.Strings",
typeof(Strings).Assembly);
}3. Configure the localization service:
using DynamicLocalization.Core;
using DynamicLocalization.Core.Providers;
public class MainViewModel
{
public ICultureService LocalizationService { get; }
public MainViewModel()
{
var cultureService = new CultureService();
var resxProvider = new ResxLocalizationProvider();
resxProvider.Initialize(new ResxLocalizationProviderOptions
{
ResourceType = typeof(Strings)
});
cultureService.RegisterProvider(resxProvider);
LocalizationService = cultureService;
}
public void SwitchToEnglish() => LocalizationService.SetCulture("en");
public void SwitchToChinese() => LocalizationService.SetCulture("zh-CN");
}4. Bind to the panel:
<auto:AvaloniaAutoSettingPanel
Targets="{Binding Targets}"
LocalizationService="{Binding LocalizationService}" />DynamicLocalization supports multiple data sources for translations:
| Provider | Description |
|---|---|
ResxLocalizationProvider |
Uses .NET .resx resource files |
JsonLocalizationProvider |
JSON file-based translations |
| Custom Provider | Implement ILocalizationProvider for database, API, etc. |
For more providers and advanced usage, see DynamicLocalization.
| Attribute | Target | Description |
|---|---|---|
[SettingUI] |
Class | Marks class for UI generation |
[MainHeader] |
Class | Sets section header title |
[Title] |
Property | Sets property label |
[SubHeader] |
Property | Creates a sub-section |
[Hide] |
Property | Excludes from UI |
[Range] |
Property | Numeric range (renders slider) |
[ItemsSource] |
Property | Dropdown items source |
[ControlBinding] |
Property | Custom control binding |
[ReadOnly] |
Property | Makes property read-only |
[Password] |
Property | Masks input (password box) |
[Placeholder] |
Property | Placeholder text for input |
[Layout] |
Property | Custom layout (width, height) |
[Validation] |
Property | Custom validation method |
[DisplayOrder] |
Property | Controls display order (lower = first) |
| Attribute | Framework | Description |
|---|---|---|
[CheckBox] |
All | Boolean property as CheckBox |
[DatePicker] |
All | DateTime with date picker |
[TimePicker] |
Avalonia/Ursa | TimeSpan with time picker |
[NumericUpDown] |
Avalonia/Ursa | Numeric input with up/down buttons |
[ColorPicker] |
Avalonia/Ursa | Color selection |
[TagInput] |
Ursa | String collection as tags |
[IPv4Box] |
Ursa | IP address input |
Note: ColorPicker requires
<StyleInclude Source="avares://Avalonia.Controls.ColorPicker/Themes/Fluent/Fluent.xaml"/>inApp.axaml.
Create custom control attributes by inheriting from ControlBindingAttribute:
[AttributeUsage(AttributeTargets.Property)]
public sealed class DatePickerAttribute : ControlBindingAttribute
{
public DatePickerAttribute()
: base(typeof(CalendarDatePicker), "SelectedDate") { }
}For complex controls, use factory methods:
public sealed class NumericUpDownAttribute : ControlBindingAttribute
{
public double Minimum { get; set; }
public double Maximum { get; set; } = 100;
public NumericUpDownAttribute()
: base(typeof(NumericUpDown), "Value", nameof(CreateControl)) { }
public Control CreateControl(Type propertyType) => new NumericUpDown
{
Minimum = (decimal)Minimum,
Maximum = (decimal)Maximum
};
}The repository includes demo applications showcasing all features:
| Demo | Framework | Description |
|---|---|---|
AutoSettingUI.Avalonia.CrossPlatform.Demo |
Avalonia | Cross-platform (Desktop, Android, iOS, Browser) |
AutoSettingUI.Ursa.Demo |
Ursa | Ursa-themed Avalonia with extended controls |
AutoSettingUI.Wpf.Demo |
WPF | Windows Presentation Foundation |
- ✅ Dynamic language switching (English/Chinese)
- ✅ Theme switching (Light/Dark/System)
- ✅ Navigation toggle
- ✅ Custom styled panels
- ✅ Extended controls demonstration
- ✅ Collection editing
| Package | Description | Dependencies |
|---|---|---|
AutoSettingUI.Avalonia |
Avalonia UI panel | Core, Extension.Shared |
AutoSettingUI.Ursa |
Ursa-themed Avalonia panel | Core, Extension.Shared |
AutoSettingUI.WPF |
WPF panel | Core, Extension.Shared |
AutoSettingUI.Generator |
Roslyn Source Generator for AOT | Standalone (Analyzer) |
AutoSettingUI.Core |
Attributes, interfaces, models | DynamicLocalization.Core |
Note:
CoreandExtension.Sharedare automatically included when installing UI framework packages.
- Architecture — Project structure and data flow
- Attributes Reference — All available attributes
- Framework Extensions — Framework-specific usage
- AOT Source Generator — AOT support details
# Debug build
.\build-all.ps1
# Release build with NuGet packages
.\build-all.ps1 -Configuration Release -Pack
# Publish demo applications
.\publish-demo.ps1 -Framework Avalonia -Mode AOT
.\publish-demo.ps1 -Framework Ursa -Mode Normal
.\publish-demo.ps1 -Framework WPF -Mode NormalMIT