MVVM Pattern
Binding Modes
| Mode | XAML | View | ViewModel |
|---|---|---|---|
| View-first | ViewModelLocator.AutoWireViewModel="True" |
XAML / DI shell / new |
From DI |
| ViewModel-first | ContentControl Content="{Binding Vm}" |
ViewLocator creates |
From DI |
Registration
AddMvvmTransient / AddMvvmSingleton register ViewModel in DI and record View mapping only:
services.AddMvvmTransient<MainView, MainViewModel>();
services.AddMvvmSingleton<AboutView, AboutViewModel>();
Shell views (MainWindow, etc.) are not in DI — use CreateShell:
CreateShell<MainWindow, MainView>();
ILifecycleAware (Optional)
Implement on ViewModel for automatic OnLoadedAsync / OnUnloaded:
public partial class MainViewModel : ObservableObject, ILifecycleAware
{
public Task OnLoadedAsync() => LoadDataAsync();
public Task OnUnloaded() => SaveStateAsync();
}
Tab / WebView:
OnUnloadedfires when leaving visual tree — manage caching in your app if needed.
API Summary
| API | Description |
|---|---|
AddMvvmTransient<TView, TViewModel>() |
AddTransient<TViewModel>() + mapping |
AddMvvmSingleton<TView, TViewModel>() |
AddSingleton<TViewModel>() + mapping |
CreateShell<TWindow, TView>() |
Create shell with new by platform lifetime |
ILifecycleAware |
Optional load/unload hooks |
Further Reading
How it works: Architecture — MVVM Wiring —
ViewModelLocatorvsViewLocator, mapping dictionaries, and lifecycle binding. Design Decisions — why View is not in DI.