
Avalonia Viewmodels Zafiro
- 544 installs
- 44k repo stars
- Updated July 27, 2026
- sickn33/antigravity-awesome-skills
Avalonia-viewmodels-zafiro is an agent skill that wires Avalonia desktop UI to Zafiro ViewModels with DataTypeViewLocator, DI composition roots, and scoped ViewModel registration so developers who build .NET desktop apps
About
Avalonia-viewmodels-zafiro is a .NET desktop development skill for Zafiro on Avalonia. It documents registering DataTypeViewLocator in App.axaml, including Zafiro data templates, and setting up dependency-injection composition roots with scoped ViewModel lifetimes so each view resolves the correct ViewModel by type. Developers reach for avalonia-viewmodels-zafiro when Avalonia screens fail to resolve views, DI scopes leak state, or ViewModel-to-View conventions need alignment with Zafiro naming patterns.
- Registers DataTypeViewLocator in App.axaml for automatic ViewModel-to-View mapping by data type
- Includes Zafiro.Avalonia DataTemplateInclude for shared framework templates
- Defines a CompositionRoot that builds ServiceCollection, AddViewModels, AddUIServices, and resolves IShellViewModel
- Shows ViewModel DI registration with Transient, Scoped, or Singleton lifetimes
- Documents naming conventions and source-generator registration patterns used in Zafiro projects
Avalonia Viewmodels Zafiro by the numbers
- 544 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #27 of 154 .NET & C# skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill avalonia-viewmodels-zafiroAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 544 |
|---|---|
| repo stars | ★ 44k |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 27, 2026 |
| Repository | sickn33/antigravity-awesome-skills ↗ |
How do you map Avalonia views to Zafiro ViewModels?
Wire Avalonia desktop UI to Zafiro ViewModels with DataTypeViewLocator, DI composition root, and scoped ViewModel registration.
Who is it for?
C# developers building Avalonia desktop apps with the Zafiro toolkit who need reliable ViewModel resolution and DI wiring.
Skip if: WPF-only apps, MAUI mobile projects, or Avalonia apps without the Zafiro ViewModel conventions.
When should I use this skill?
A developer sets up Zafiro ViewModels, DataTypeViewLocator, or DI scopes in a new Avalonia desktop project.
What you get
App.axaml DataTypeViewLocator setup, ViewModel-to-View mappings, and DI composition root with scoped registrations.
- App.axaml locator config
- DI registration pattern
- ViewModel mapping setup
Files
Avalonia ViewModels with Zafiro
This skill provides a set of best practices and patterns for creating ViewModels, Wizards, and managing navigation in Avalonia applications, leveraging the power of ReactiveUI and the Zafiro toolkit.
Core Principles
1. Functional-Reactive Approach: Use ReactiveUI (ReactiveObject, WhenAnyValue, etc.) to handle state and logic. 2. Enhanced Commands: Utilize IEnhancedCommand for better command management, including progress reporting and name/text attributes. 3. Wizard Pattern: Implement complex flows using SlimWizard and WizardBuilder for a declarative and maintainable approach. 4. Automatic Section Discovery: Use the [Section] attribute to register and discover UI sections automatically. 5. Clean Composition: map ViewModels to Views using DataTypeViewLocator and manage dependencies in the CompositionRoot.
Guides
- ViewModels & Commands: Creating robust ViewModels and handling commands.
- Wizards & Flows: Building multi-step wizards with
SlimWizard. - Navigation & Sections: Managing navigation and section-based UIs.
- Composition & Mapping: Best practices for View-ViewModel wiring and DI.
Example Reference
For real-world implementations, refer to the Angor project:
CreateProjectFlowV2.cs: Excellent example of complex Wizard building.HomeViewModel.cs: Simple section ViewModel using functional-reactive commands.
When to Use
This skill is applicable to execute the workflow or actions described in the overview.
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
Composition & Mapping
Ensuring your ViewModels are correctly instantiated and mapped to their corresponding Views is crucial for a maintainable application.
ViewModel-to-View Mapping
Zafiro uses the DataTypeViewLocator to automatically map ViewModels to Views based on their data type.
Integration in App.axaml
Register the DataTypeViewLocator in your application's data templates:
<Application.DataTemplates>
<DataTypeViewLocator />
<DataTemplateInclude Source="avares://Zafiro.Avalonia/DataTemplates.axaml" />
</Application.DataTemplates>Registration
Mappings can be registered globally or locally. Common practice in Zafiro projects is to use naming conventions or explicit registrations made by source generators.
Composition Root
Use a central CompositionRoot to manage dependency injection and service registration.
public static class CompositionRoot
{
public static IShellViewModel CreateMainViewModel(Control topLevelView)
{
var services = new ServiceCollection();
services
.AddViewModels()
.AddUIServices(topLevelView);
var serviceProvider = services.BuildServiceProvider();
return serviceProvider.GetRequiredService<IShellViewModel>();
}
}Registering ViewModels
Register ViewModels with appropriate scopes (Transient, Scoped, or Singleton).
public static IServiceCollection AddViewModels(this IServiceCollection services)
{
return services
.AddTransient<IHomeSectionViewModel, HomeSectionSectionViewModel>()
.AddSingleton<IShellViewModel, ShellViewModel>();
}View Injection
Use the Connect helper (if available) or manual instantiation in OnFrameworkInitializationCompleted:
public override void OnFrameworkInitializationCompleted()
{
this.Connect(
() => new ShellView(),
view => CompositionRoot.CreateMainViewModel(view),
() => new MainWindow());
base.OnFrameworkInitializationCompleted();
}[!TIP]
UseActivatorUtilities.CreateInstancewhen you need to manually instantiate a class while still resolving its dependencies from theIServiceProvider.
Navigation & Sections
Zafiro provides powerful abstractions for managing application-wide navigation and modular UI sections.
Navigation with INavigator
The INavigator interface is used to switch between different views or viewmodels.
public class MyViewModel(INavigator navigator)
{
public async Task GoToDetails()
{
await navigator.Navigate(() => new DetailsViewModel());
}
}UI Sections
Sections are modular parts of the UI (like tabs or sidebar items) that can be automatically registered.
The [Section] Attribute
ViewModels intended to be sections should be marked with the [Section] attribute.
[Section("Wallet", icon: "fa-wallet")]
public class WalletSectionViewModel : IWalletSectionViewModel
{
// ...
}Automatic Registration
In the CompositionRoot, sections can be automatically registered:
services.AddAnnotatedSections(logger);
services.AddSectionsFromAttributes(logger);Switching Sections
You can switch the current active section via the IShellViewModel:
shellViewModel.SetSection("Browse");[!IMPORTANT]
Theiconparameter in the[Section]attribute supports FontAwesome icons (e.g.,fa-home) when configured withProjektankerIconControlProvider.
ViewModels & Commands
In a Zafiro-based application, ViewModels should be functional, reactive, and resilient.
Reactive ViewModels
Use ReactiveObject as the base class. Properties should be defined using the [Reactive] attribute (from ReactiveUI.SourceGenerators) for brevity.
public partial class MyViewModel : ReactiveObject
{
[Reactive] private string name;
[Reactive] private bool isBusy;
}Observation and Transformation
Use WhenAnyValue to react to property changes:
this.WhenAnyValue(x => x.Name)
.Select(name => !string.IsNullOrEmpty(name))
.ToPropertyEx(this, x => x.CanSubmit);Enhanced Commands
Zafiro uses IEnhancedCommand, which extends ICommand and IReactiveCommand with additional metadata like Name and Text.
Creating a Command
Use ReactiveCommand.Create or ReactiveCommand.CreateFromTask and then Enhance() it.
public IEnhancedCommand Submit { get; }
public MyViewModel()
{
Submit = ReactiveCommand.CreateFromTask(OnSubmit, canSubmit)
.Enhance(text: "Submit Data", name: "SubmitCommand");
}Error Handling
Use HandleErrorsWith to automatically channel command errors to the NotificationService.
Submit.HandleErrorsWith(uiServices.NotificationService, "Submission Failed")
.DisposeWith(disposable);Disposables
Always use a CompositeDisposable to manage subscriptions and command lifetimes.
public class MyViewModel : ReactiveObject, IDisposable
{
private readonly CompositeDisposable disposables = new();
public void Dispose() => disposables.Dispose();
}[!TIP]
Use .DisposeWith(disposables) on any observable subscription or command to ensure proper cleanup.Wizards & Flows
Complex multi-step processes are handled using the SlimWizard pattern. This provides a declarative way to define steps, navigation logic, and final results.
Defining a Wizard
Use WizardBuilder to define the steps. Each step corresponds to a ViewModel.
SlimWizard<string> wizard = WizardBuilder
.StartWith(() => new Step1ViewModel(data))
.NextUnit()
.WhenValid()
.Then(prevResult => new Step2ViewModel(prevResult))
.NextCommand(vm => vm.CustomNextCommand)
.Then(result => new SuccessViewModel("Done!"))
.Next((_, s) => s, "Finish")
.WithCompletionFinalStep();Navigation Rules
- NextUnit(): Advances when a simple signal is emitted.
- NextCommand(): Advances when a specific command in the ViewModel execution successfully.
- WhenValid(): Wait until the current ViewModel's validation passes before allowing navigation.
- Always(): Navigation is always allowed.
Navigation Integration
The wizard is navigated using an INavigator:
public async Task CreateSomething()
{
var wizard = BuildWizard();
var result = await wizard.Navigate(navigator);
// Handle result
}Step Configuration
- WithCompletionFinalStep(): Marks the wizard as finished when the last step completes.
- WithCommitFinalStep(): Typically used for wizards that perform a final "Save" or "Deploy" action.
[!NOTE]
The SlimWizard handles the "Back" command automatically, providing a consistent user experience across different flows.Related skills
How it compares
Choose avalonia-viewmodels-zafiro for Zafiro-specific Avalonia MVVM wiring; use general Avalonia docs for apps not using Zafiro conventions.
FAQ
How does avalonia-viewmodels-zafiro map views to ViewModels?
Avalonia-viewmodels-zafiro uses Zafiro's DataTypeViewLocator in App.axaml so Avalonia automatically selects Views based on each ViewModel's CLR type, following project naming conventions.
Where is DataTypeViewLocator registered?
Avalonia-viewmodels-zafiro registers DataTypeViewLocator inside Application.DataTemplates in App.axaml alongside Zafiro.Avalonia DataTemplateInclude sources for shared templates.
Is Avalonia Viewmodels Zafiro safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.