mcpField
A
avalonia-mvvm

avalonia-mvvm

github.com/abdssamie开发260 次安装25 周前更新
代码仓库

关于 avalonia-mvvm

avalonia-mvvm 是一份在 Avalonia 应用中使用 CommunityToolkit.Mvvm 模式的指南,涵盖 ViewModel、导航、命令、验证和依赖注入。

主要功能

  1. 01使用 ObservableObject 构建 ViewModel
  2. 02通过特性创建可观察属性
  3. 03实现同步和异步命令
  4. 04使用 DataTemplates 映射 View 与 ViewModel
  5. 05通过依赖注入传递服务
  6. 06添加属性验证

适用场景

  1. 01为 Avalonia 视图创建 ViewModel
  2. 02添加可通知 UI 的属性和命令
  3. 03设置由 ViewModel 驱动的导航
  4. 04验证 ViewModel 属性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/abdssamie/quater --skill avalonia-mvvm

安装后在 Claude Code 中输入/avalonia-mvvm确认已加载。

详细介绍

Avalonia 中的 MVVM 模式

在 Avalonia 应用程序中使用 CommunityToolkit.Mvvm 的 MVVM 模式完整指南。

我能做什么

  • 指导如何使用 ObservableObject 基类实现 ViewModel
  • 展示如何使用 [ObservableProperty] 特性创建可观察属性
  • 演示包含异步和 CanExecute 的 [RelayCommand] 命令模式
  • 说明如何使用 DataTemplates 将 View 映射到 ViewModel(对导航至关重要)
  • 展示如何通过依赖注入将服务传递给 ViewModel

何时使用我

在需要以下操作时使用此技能:

  • 为 Avalonia 视图创建新的 ViewModel
  • 实现可观察属性,以便在属性变化时通知 UI
  • 添加命令以处理用户交互(按钮点击等)
  • 使用 SukiSideMenu 或 ContentControl 设置导航模式
  • 在 ViewModel 之间传递服务(例如 ISukiToastManager)
  • 为 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 = "";
带属性变更通知的属性
[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;
}

视图:

<Button Content="Save" 
        Command="{Binding ButtonClickCommand}" 
        CommandParameter="Save Button" />
异步命令
[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

使用导航模式将 ViewModel 显示在 ContentControl 中(例如 SukiSideMenu)时,必须定义 DataTemplates,将 ViewModel 映射到对应的 View。

在 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;
    }
}

应避免的常见错误

  1. 忘记定义 DataTemplates——没有 ViewModel 到 View 的映射,导航将无法工作
  2. 未使用 partial 类——CommunityToolkit.Mvvm 要求使用 partial 关键字
  3. 缺少 OnPropertyChanged——没有手动通知,计算属性不会更新
  4. 未调用 NotifyCanEuteChanged——带 CanExecute 的命令不会自动重新评估
  5. 字段命名错误——可观察属性对应的字段必须以一个下划线开头,并声明为 private

最佳实践

  1. 始终在 ViewModel 上使用 partial 关键字
  2. 使用 [ObservableProperty],而不是手动实现 INotifyPropertyChanged
  3. 使用 [RelayCommand],而不是手动实现 ICommand
  4. 在根窗口中定义 DataTemplates,以支持导航场景
  5. 通过构造函数注入传递服务
  6. 使用计算属性获取派生值
  7. 为需要验证的属性添加验证特性

评论

支持 Markdown