[ PROMPT_NODE_23728 ]
viewmodels
[ SKILL_DOCUMENTATION ]
# ViewModel 与命令
在基于 Zafiro 的应用程序中,ViewModel 应该是功能性的、响应式的且具有弹性的。
## 响应式 ViewModel
使用 `ReactiveObject` 作为基类。为了简洁起见,应使用 `[Reactive]` 特性(来自 ReactiveUI.SourceGenerators)定义属性。
csharp
public partial class MyViewModel : ReactiveObject
{
[Reactive] private string name;
[Reactive] private bool isBusy;
}
### 观察与转换
使用 `WhenAnyValue` 来响应属性更改:
csharp
this.WhenAnyValue(x => x.Name)
.Select(name => !string.IsNullOrEmpty(name))
.ToPropertyEx(this, x => x.CanSubmit);
## 增强命令
Zafiro 使用 `IEnhancedCommand`,它扩展了 `ICommand` 和 `IReactiveCommand`,并增加了如 `Name` 和 `Text` 等附加元数据。
### 创建命令
使用 `ReactiveCommand.Create` 或 `ReactiveCommand.CreateFromTask`,然后调用 `Enhance()`。
csharp
public IEnhancedCommand Submit { get; }
public MyViewModel()
{
Submit = ReactiveCommand.CreateFromTask(OnSubmit, canSubmit)
.Enhance(text: "Submit Data", name: "SubmitCommand");
}
### 错误处理
使用 `HandleErrorsWith` 自动将命令错误引导至 `NotificationService`。
csharp
Submit.HandleErrorsWith(uiServices.NotificationService, "Submission Failed")
.DisposeWith(disposable);
## 资源释放 (Disposables)
始终使用 `CompositeDisposable` 来管理订阅和命令的生命周期。
csharp
public class MyViewModel : ReactiveObject, IDisposable
{
private readonly CompositeDisposable disposables = new();
public void Dispose() => disposables.Dispose();
}
> [!TIP]
> 在任何可观察订阅或命令上使用 `.DisposeWith(disposables)` 以确保正确清理。