Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Modell-View-ViewModel (MVVM) är ett designmönster för användargränssnitt som frikopplar UI-kod och icke-UI-kod. Lär dig hur MVVM möjliggör lös koppling med hjälp av databindning i XAML för att synkronisera användargränssnitt och data, förbättra underhållsbarheten och minska beroenden.
Eftersom den ger lös koppling minskar användningen av databindning hårda beroenden mellan olika typer av kod. Den här metoden gör det enklare att ändra enskilda kodenheter (metoder, klasser, kontroller och så vidare) utan att orsaka oavsiktliga biverkningar i andra enheter. Den här avkopplingen är ett exempel på uppdelningen av problem, vilket är ett viktigt begrepp i många designmönster.
Tips/Råd
När du ska använda MVVM: Använd MVVM för appar med komplexa dataflöden, flera skärmar eller teamutvecklade kodbaser. För enkla verktyg på en sida eller prototyper är code-behind acceptabelt – du kan införa MVVM stegvis i takt med att komplexiteten ökar. Om din app har enhetstestbar affärslogik gör MVVM att logiken kan testas utan ett användargränssnitt som körs.
Fördelar med MVVM
Det finns många fördelar med att koppla bort koden, bland annat:
- Aktivera ett iterativt, undersökande kodningsformat. Ändringar som är isolerade är mindre riskfyllda och enklare att experimentera med.
- Förenkla enhetstestning. Du kan testa kodenheter som är isolerade från varandra individuellt och utanför produktionsmiljöer.
- Stöd för teamsamarbete. Separata individer eller team kan utveckla frikopplad kod som följer väl utformade gränssnitt och integrerar den senare.
- Förbättra underhållsbarheten. Att åtgärda buggar i frikopplad kod är mindre sannolikt att orsaka regressioner i annan kod.
Till skillnad från MVVM använder en app med en mer konventionell "code-behind"-struktur vanligtvis databindning för visningsdata. Den svarar på användarindata genom att direkt hantera händelser som exponeras av kontroller. Händelsehanterarna implementeras i kod bakom filer (till exempel MainWindow.xaml.cs) och är ofta nära kopplade till kontrollerna. De innehåller vanligtvis kod som manipulerar användargränssnittet direkt. Den här strukturen gör det svårt eller omöjligt att ersätta en kontroll utan att behöva uppdatera händelsehanteringskoden. Med den här arkitekturen ackumulerar kod bakom filer ofta kod som inte är direkt relaterad till användargränssnittet, till exempel kod för databasåtkomst, som i slutänden dupliceras och ändras för användning med andra fönster.
Applager
När du använder MVVM-mönstret delar du upp appen i följande lager:
- Modellskiktet definierar de typer som representerar dina affärsdata. Det här lagret innehåller allt som krävs för att modellera kärnappdomänen och innehåller ofta kärnapplogik. Det här lagret är helt oberoende av skikten för vy och vymodell och finns ofta delvis i molnet. Med ett fullständigt implementerat modelllager kan du skapa flera olika klientappar om du väljer, till exempel Windows App SDK och webbappar som fungerar med samma underliggande data.
- Visningslagret definierar användargränssnittet med XAML-markering. Markupen innehåller databindningsuttryck (till exempel x:Bind) som definierar kopplingen mellan specifika UI-komponenter och olika medlemmar i vy- och modellskiktslagret. Du kan ibland använda kod bakom filer som en del av visningslagret för att innehålla ytterligare kod som behövs för att anpassa eller ändra användargränssnittet eller för att extrahera data från händelsehanterarargument innan du anropar en view-model-metod som utför arbetet.
- Visningsmodelllagret innehåller databindningsmål för vyn. I många fall exponerar vymodellen modellen direkt eller tillhandahåller medlemmar som omsluter specifika modellmedlemmar. Vymodellen kan också definiera medlemmar för att hålla reda på data som är relevanta för användargränssnittet men inte för modellen, till exempel visningsordningen för en lista med objekt. Vymodellen fungerar också som en integrationsplats med andra tjänster, till exempel dataåtkomstkod. För enkla projekt behöver du kanske inte ett separat modelllager, utan bara en vymodell som kapslar in alla data du behöver.
Grundläggande och avancerad MVVM
Precis som med alla designmönster finns det mer än ett sätt att implementera MVVM, och många olika tekniker anses vara en del av MVVM. Därför finns det flera olika MVVM-ramverk från tredje part som stöder de olika XAML-baserade plattformarna, inklusive Windows App SDK. Dessa ramverk omfattar dock i allmänhet flera tjänster för att implementera frikopplad arkitektur, vilket gör den exakta definitionen av MVVM något tvetydig.
Även om avancerade MVVM-ramverk kan vara mycket användbara, särskilt för projekt i företagsskala, finns det vanligtvis en kostnad som är förknippad med att införa ett visst mönster eller teknik, och fördelarna är inte alltid tydliga, beroende på projektets skala och storlek. Lyckligtvis kan du bara använda de tekniker som ger en tydlig och påtaglig fördel och ignorera andra tills du behöver dem.
I synnerhet kan du få stor nytta genom att helt enkelt förstå och tillämpa den fulla kraften i databindning och separera din applogik i de lager som beskrevs tidigare. Detta kan endast uppnås med hjälp av de funktioner som tillhandahålls av Windows App SDK och utan att använda några externa ramverk. I synnerhet gör markeringstillägget {x:Bind} databindningen enklare och bättre än i tidigare XAML-plattformar, vilket eliminerar behovet av mycket av den pannplåtskod som krävdes tidigare.
Mer information om hur du använder MVVM finns i CommunityToolkit MVVM-biblioteket , som tillhandahåller basklasser som ObservableObject och RelayCommand, tillsammans med källgeneratorer (via [ObservableProperty] och [RelayCommand] attribut) som eliminerar boilerplate-kod.
WinUI-galleriet visar även databindning och MVVM-mönster med WinUI 3.
CommunityToolkit.Mvvm-exempel
I följande exempel visas en fullständig ViewModel med hjälp av CommunityToolkit.Mvvm 8.x-källgeneratorer. Attributet [ObservableProperty] genererar egenskapen och ändringsmeddelandet och [RelayCommand] genererar implementeringen ICommand :
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public partial class CustomerViewModel : ObservableObject
{
private readonly ICustomerService _customerService;
public CustomerViewModel(ICustomerService customerService)
{
_customerService = customerService;
}
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(SaveCommand))]
private string _name = string.Empty;
[ObservableProperty]
private bool _isBusy;
[RelayCommand(CanExecute = nameof(CanSave))]
private async Task SaveAsync()
{
IsBusy = true;
await _customerService.SaveAsync(Name);
IsBusy = false;
}
private bool CanSave() => !string.IsNullOrWhiteSpace(Name);
}
Binda den här ViewModel till en sida med hjälp av {x:Bind}:
<Page x:Class="MyApp.Views.CustomerPage"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Save" Command="{x:Bind ViewModel.SaveCommand}" />
<ProgressRing IsActive="{x:Bind ViewModel.IsBusy, Mode=OneWay}" />
</StackPanel>
</Page>
Sidans kod bakom exponerar egenskapen ViewModel som {x:Bind} refererar till:
// CustomerPage.xaml.cs
public sealed partial class CustomerPage : Page
{
public CustomerViewModel ViewModel { get; }
public CustomerPage()
{
// Resolve via DI; see Architecture patterns for WinUI 3 desktop apps
// for how to configure App.GetService<T>() with Microsoft.Extensions.DependencyInjection.
ViewModel = App.GetService<CustomerViewModel>();
InitializeComponent();
}
}
Vägledning om hur du kombinerar MVVM med beroendeinmatning, konfiguration och företagsmönster finns i Arkitekturmönster för WinUI 3-skrivbordsappar.
Se även
Ämnen
Databindning på djupet
{x:Bind} markup-extension
MVVM-prestandatips för WinUI-appar
Arkitekturmönster för WinUI 3-skrivbordsappar
WinUI 3- och MVVM-resurser
Dokumentation om CommunityToolkit MVVM
WinUI-galleriet – databindningsexempel
Template Studio för WinUI
Windows developer