avalonia-mvvm
Avaloniaアプリケーションで、ViewModelやCommand、Dependency InjectionといったMVVMパターンを、CommunityToolkit.Mvvmを使って効率的に実装し、より構造化された開発を実現するSkill。
📜 元の英語説明(参考)
Implement MVVM patterns using CommunityToolkit.Mvvm in Avalonia applications with ViewModels, Commands, and Dependency Injection
🇯🇵 日本人クリエイター向け解説
Avaloniaアプリケーションで、ViewModelやCommand、Dependency InjectionといったMVVMパターンを、CommunityToolkit.Mvvmを使って効率的に実装し、より構造化された開発を実現するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o avalonia-mvvm.zip https://jpskill.com/download/8810.zip && unzip -o avalonia-mvvm.zip && rm avalonia-mvvm.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/8810.zip -OutFile "$d\avalonia-mvvm.zip"; Expand-Archive "$d\avalonia-mvvm.zip" -DestinationPath $d -Force; ri "$d\avalonia-mvvm.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
avalonia-mvvm.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
avalonia-mvvmフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Avalonia における MVVM パターン
Avalonia アプリケーションで CommunityToolkit.Mvvm を使用した MVVM パターンの完全なガイドです。
私の役割
ObservableObject基底クラスを使用した ViewModel の実装をガイドします[ObservableProperty]属性を使用して、監視可能なプロパティを作成する方法を示します[RelayCommand]を使用したコマンドパターンを、async および CanExecute を含めて説明します- DataTemplates を使用した View-ViewModel マッピングを説明します (ナビゲーションに不可欠)
- サービスを ViewModel に渡すための依存性注入パターンを示します
私を使うべき時
以下が必要な場合は、このスキルを使用してください。
- Avalonia ビュー用の新しい ViewModel を作成する
- UI に変更を通知する監視可能なプロパティを実装する
- ユーザーインタラクション (ボタンクリックなど) を処理するコマンドを追加する
- SukiSideMenu または ContentControl を使用してナビゲーションパターンを設定する
- サービス (例:
ISukiToastManager) を ViewModel 間で渡す - ViewModel プロパティの検証を実装する
ViewModel 基底クラス
基本的な ViewModel
using CommunityToolkit.Mvvm.ComponentModel;
namespace YourApp.ViewModels;
public partial class ViewModelBase : ObservableObject
{
}
ページ ViewModel 基底クラス
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 = "";
Property Changed Notification 付き
[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" />
Async コマンド
[RelayCommand]
private async Task LoadDataAsync()
{
IsLoading = true;
await Task.Delay(1000);
IsLoading = false;
}
CanExecute 付きコマンド
[ObservableProperty]
private bool _isDataLoaded;
[RelayCommand(CanExecute = nameof(CanSave))]
private void Save()
{
// Save logic
}
private bool CanSave() => IsDataLoaded;
partial void OnIsDataLoadedChanged(bool value)
{
SaveCommand.NotifyCanExecuteChanged();
}
重要なパターン: DataTemplates
ViewModels が ContentControl (SukiSideMenu など) に表示されるナビゲーションパターンを使用する場合、ViewModels を対応する Views にマッピングするために DataTemplates を定義する必要があります。
SukiWindow 内:
<suki:SukiWindow.DataTemplates>
<DataTemplate DataType="vm:HomePageViewModel">
<views:HomePage />
</DataTemplate>
<DataTemplate DataType="vm:SettingsPageViewModel">
<views:SettingsPage />
</DataTemplate>
</suki:SukiWindow.DataTemplates>
依存性注入
サービスを ViewModel に渡す
親 ViewModel:
public partial class MainWindowViewModel : ViewModelBase
{
private readonly ISukiToastManager _toastManager;
public MainWindowViewModel()
{
_toastManager = new SukiToastManager();
Pages = new ObservableCollection<PageViewModelBase>
{
new NotificationsPageViewModeler)
};
}
}
子 ViewModel:
public partial class NotificationsPageViewModel : PageViewModelBase
{
private readonly ISukiToastManager _toastManager;
public NotificationsPageViewModel(ISukiToastManager toastManager)
{
_toastManager = toastManager;
}
}
避けるべき一般的な間違い
- DataTemplates を忘れる - ViewModel から View へのマッピングがないとナビゲーションは機能しません
- partial class を使用しない - CommunityToolkit.Mvvm には partial キーワードが必要です
- OnPropertyChanged がない - 計算されたプロパティは手動で通知しないと更新されません
- NotifyCanEuteChanged を呼び出さない - CanExecute を持つコマンドは自動的に再評価されません
- 間違ったフィールド命名を使用する - 監視可能なプロパティフィールドはアンダースコアで始まり、private である必要があります
ベストプラクティス
- 常に ViewModel で partial キーワードを使用する
- 手動の
INotifyPropertyChangedの代わりに[ObservableProperty]を使用する - 手動の
ICommand実装の代わりに[RelayCommand]を使用する - ナビゲーションシナリオでは、ルートウィンドウで DataTemplates を定義する
- コンストラクタインジェクションを介してサービスを渡す
- 派生値には計算されたプロパティを使用する
- 検証が必要なプロパティに検証属性を実装する
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
MVVM Patterns in Avalonia
Complete guide to MVVM patterns using CommunityToolkit.Mvvm in Avalonia applications.
What I do
- Guide implementation of ViewModels with ObservableObject base class
- Show how to create observable properties with [ObservableProperty] attribute
- Demonstrate command patterns with [RelayCommand] including async and CanExecute
- Explain View-ViewModel mapping using DataTemplates (critical for navigation)
- Show dependency injection patterns for passing services to ViewModels
When to use me
Use this skill when you need to:
- Create new ViewModels for Avalonia views
- Implement observable properties that notify the UI of changes
- Add commands to handle user interactions (button clicks, etc.)
- Set up navigation patterns with SukiSideMenu or ContentControl
- Pass services (like ISukiToastManager) between ViewModels
- Implement validation on ViewModel properties
ViewModel Base Classes
Basic ViewModel
using CommunityToolkit.Mvvm.ComponentModel;
namespace YourApp.ViewModels;
public partial class ViewModelBase : ObservableObject
{
}
Page ViewModel Base
using CommunityToolkit.Mvvm.ComponentModel;
namespace YourApp.ViewModels;
public abstract partial class PageViewModelBase : ViewModelBase
{
public abstract string DisplayName { get; }
public abstract string Icon { get; }
}
Observable Properties
Basic Observable Property
[ObservableProperty]
private string _name = "";
With Validation
using System.ComponentModel.DataAnnotations;
[ObservableProperty]
[Required(ErrorMessage = "Name is required")]
[MinLength(3, ErrorMessage = "Name must be at least 3 characters")]
private string _name = "";
With Property Changed Notification
[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));
}
Commands
Basic Command
[RelayCommand]
private void Save()
{
// Save logic
}
Command with Parameter
[RelayCommand]
private void ButtonClick(string buttonName)
{
LastButtonClicked = buttonName;
}
View:
<Button Content="Save"
Command="{Binding ButtonClickCommand}"
CommandParameter="Save Button" />
Async Command
[RelayCommand]
private async Task LoadDataAsync()
{
IsLoading = true;
await Task.Delay(1000);
IsLoading = false;
}
Command with CanExecute
[ObservableProperty]
private bool _isDataLoaded;
[RelayCommand(CanExecute = nameof(CanSave))]
private void Save()
{
// Save logic
}
private bool CanSave() => IsDataLoaded;
partial void OnIsDataLoadedChanged(bool value)
{
SaveCommand.NotifyCanExecuteChanged();
}
Critical Pattern: DataTemplates
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>
Dependency Injection
Passing Services to ViewModels
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;
}
}
Common Mistakes to Avoid
- Forgetting DataTemplates - Navigation won't work without ViewModel-to-View mapping
- Not using partial class - CommunityToolkit.Mvvm requires partial keyword
- Missing OnPropertyChanged - Computed properties won't update without manual notification
- Not calling NotifyCanEuteChanged - Commands with CanExecute won't re-evaluate automatically
- Using wrong field naming - Observable property fields must start with underscore and be private
Best Practices
- Always use partial keyword on ViewModels
- Use [ObservableProperty] instead of manual INotifyPropertyChanged
- Use [RelayCommand] instead of manual ICommand implementation
- Define DataTemplates in the root window for navigation scenarios
- Pass services through constructor injection
- Use computed properties for derived values
- Implement validation attributes on properties need validation