avalonia-mvvm
Implement MVVM patterns using CommunityToolkit.Mvvm in Avalonia applications with ViewModels, Commands, and Dependency Injection
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Implement MVVM patterns using CommunityToolkit.Mvvm in Avalonia applications with ViewModels, Commands, and Dependency Injection
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Quick reference for Avalonia XAML (AXAML) syntax including namespaces, property syntax, bindings, styles, and SukiUI patterns
A guide on working with claims in asp.net core
Guides agents on implmenting policy based authorization in Asp.net
Comprehensive guide to data binding patterns in Avalonia for AI agents.
| name | avalonia-mvvm |
| description | Implement MVVM patterns using CommunityToolkit.Mvvm in Avalonia applications with ViewModels, Commands, and Dependency Injection |
| license | MIT |
| compatibility | opencode |
| metadata | {"audience":"avalonia-developers","framework":"avalonia"} |
Complete guide to MVVM patterns using CommunityToolkit.Mvvm in Avalonia applications.
Use this skill when you need to:
using CommunityToolkit.Mvvm.ComponentModel;
namespace YourApp.ViewModels;
public partial class ViewModelBase : ObservableObject
{
}
using CommunityToolkit.Mvvm.ComponentModel;
namespace YourApp.ViewModels;
public abstract partial class PageViewModelBase : ViewModelBase
{
public abstract string DisplayName { get; }
public abstract string Icon { get; }
}
[ObservableProperty]
private string _name = "";
using System.ComponentModel.DataAnnotations;
[ObservableProperty]
[Required(ErrorMessage = "Name is required")]
[MinLength(3, ErrorMessage = "Name must be at least 3 characters")]
private string _name = "";
[ObservableProperty]
private string _firstName = "";
[ObservableProperty]
private string _lastName = "";
public string FullName => $"{FirstName} {LastName}";
partial void OnFirstNameChanged(string value)
{
OnPropertyChanged(nameof(FullName));
}
partial void OnLastNameChanged(string value)
{
OnPropertyChanged(nameof(FullName));
}
[RelayCommand]
private void Save()
{
// Save logic
}
[RelayCommand]
private void ButtonClick(string buttonName)
{
LastButtonClicked = buttonName;
}
View:
<Button Content="Save"
Command="{Binding ButtonClickCommand}"
CommandParameter="Save Button" />
[RelayCommand]
private async Task LoadDataAsync()
{
IsLoading = true;
await Task.Delay(1000);
IsLoading = false;
}
[ObservableProperty]
private bool _isDataLoaded;
[RelayCommand(CanExecute = nameof(CanSave))]
private void Save()
{
// Save logic
}
private bool CanSave() => IsDataLoaded;
partial void OnIsDataLoadedChanged(bool value)
{
SaveCommand.NotifyCanExecuteChanged();
}
When using navigation patterns where ViewModels are displayed in a ContentControl (like SukiSideMenu), you MUST define DataTemplates to map ViewModels to their corresponding Views.
In SukiWindow:
<suki:SukiWindow.DataTemplates>
<DataTemplate DataType="vm:HomePageViewModel">
<views:HomePage />
</DataTemplate>
<DataTemplate DataType="vm:SettingsPageViewModel">
<views:SettingsPage />
</DataTemplate>
</suki:SukiWindow.DataTemplates>
Parent ViewModel:
public partial class MainWindowViewModel : ViewModelBase
{
private readonly ISukiToastManager _toastManager;
public MainWindowViewModel()
{
_toastManager = new SukiToastManager();
Pages = new ObservableCollection<PageViewModelBase>
{
new NotificationsPageViewModeler)
};
}
}
Child ViewModel:
public partial class NotificationsPageViewModel : PageViewModelBase
{
private readonly ISukiToastManager _toastManager;
public NotificationsPageViewModel(ISukiToastManager toastManager)
{
_toastManager = toastManager;
}
}