Sök…


Anmärkningar

Det här avsnittet ger en översikt över vad mvvm är, och varför en utvecklare kanske vill använda den.

Det bör också nämna alla stora ämnen inom mvvm och koppla till de relaterade ämnena. Eftersom dokumentationen för mvvm är ny kan du behöva skapa initialversioner av relaterade ämnen.

C # MVVM Sammanfattning och komplett exempel

Sammanfattning:

MVVM är ett arkitektoniskt mönster som representeras av tre distinkta komponenter, Model , View och ViewModel . För att förstå dessa tre lager är det nödvändigt att kort definiera vart och ett, följt av en förklaring av hur de arbetar tillsammans.

Modellen är det lager som driver affärslogiken. Den hämtar och lagrar information från vilken datakälla som helst för konsumtion av ViewModel .

ViewModel är det lager som fungerar som en bro mellan vyn och modellen . Det kan kanske eller inte förvandla rådata från modellen till en presentabelformulär för vyn . Ett exempel på omvandling skulle vara: en boolesk flagga från modellen till strängen "Sann" eller "Falsk" för vyn.

Visa är det lager som representerar gränssnittet för programvaran (dvs. GUI). Dess roll är att visa informationen från ViewModel till användaren och att kommunicera ändringarna av informationen tillbaka till ViewModel .

Dessa tre komponenter fungerar tillsammans genom att hänvisa till varandra på följande sätt:

  • The View refererar till Viewmodel.
  • ViewModel refererar till modellen .

Det är viktigt att notera att View och ViewModel kan tvåvägskommunikationer känd som Data Bindings .

En viktig ingrediens för tvåvägskommunikation (databindande) är gränssnittet INotifyPropertyChanged .

Genom att använda denna mekanism kan View modifiera data i ViewModel genom användarinmatning, och ViewModel kan uppdatera View med data som kan ha uppdaterats via processer i modellen eller med uppdaterade data från förvaret.

MVVM-arkitekturen lägger stor vikt vid separationen av bekymmer för vart och ett av dessa lager. Att separera lagren gynnar oss som:

  • Modularitet: Varje lagers interna implementering kan ändras eller bytas utan att påverka de andra.
  • Ökad testbarhet: Varje lager kan enhetstestas med falska data, vilket inte är möjligt om ViewModels kod är skriven i koden bakom vyn .

Byggnaden:

Skapa ett nytt WPF-applikationsprojekt Skapa ett nytt WPF-applikationsprojekt

Skapa tre nya mappar i din lösning: Model , ViewModel och View och ta bort det ursprungliga MainWindow.xaml , bara för att få en ny start.

Skapa 3 nya mappar i din lösning

Skapa tre nya artiklar som var och en motsvarar ett separat lager:

  • Högerklicka på Model mappen och lägga till en klass post kallad HelloWorldModel.cs .
  • Högerklicka på mappen Viewmodel, och lägg till en klass post kallad HelloWorldViewModel.cs .
  • Högerklicka på mappen Visa och lägg till ett fönster (WPF) -objekt som heter HelloWorldView.xaml .

Lägg till de tre artiklarna

Ändra App.xaml att peka på den nya vyn

<Application x:Class="MyMVVMProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MyMVVMProject"
             StartupUri="/View/HelloWorldView.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

Viewmodel:

Börja med att bygga ViewModel först. Klassen måste implementera gränssnittet INotifyPropertyChanged , förklara en PropertyChangedEventHandler händelse och skapa en metod för att höja händelsen (källa: MSDN: How to Implement Property Change Notification ). Förklara sedan ett fält och en motsvarande egenskap och se till att anropa OnPropertyChanged() i egenskapens set accessor. Konstruktorn i exemplet nedan används för att demonstrera att modellen tillhandahåller data till ViewModel .

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using MyMVVMProject.Model;

namespace MyMVVMProject.ViewModel
{
    // Implements INotifyPropertyChanged interface to support bindings
    public class HelloWorldViewModel : INotifyPropertyChanged
    {
        private string helloString;

        public event PropertyChangedEventHandler PropertyChanged;

        public string HelloString
        {
            get
            {
                return helloString;
            }
            set
            {
                helloString = value;
                OnPropertyChanged();
            }
        }

        /// <summary>
        /// Raises OnPropertychangedEvent when property changes
        /// </summary>
        /// <param name="name">String representing the property name</param>
        protected void OnPropertyChanged([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        public HelloWorldViewModel()
        {
            HelloWorldModel helloWorldModel = new HelloWorldModel();
            helloString = helloWorldModel.ImportantInfo;
        }
    }
}

Modell:

Bygg sedan modellen . Som tidigare angivits tillhandahåller modellen data för ViewModel genom att dra den från ett förvar (samt skjuta tillbaka till förvaret för att spara). Detta visas nedan med GetData() , som kommer att returnera en enkel List<string> . Affärslogik tillämpas också i detta lager och kan ses i ConcatenateData() . Denna metod bygger meningen "Hej, världen!" från List<string> som tidigare returnerades från vårt "förvar".

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyMVVMProject.Model
{
    public class HelloWorldModel
    {
        private List<string> repositoryData;
        public string ImportantInfo
        {
            get
            {
                return ConcatenateData(repositoryData);
            }
        }

        public HelloWorldModel()
        {
            repositoryData = GetData();
        }

        /// <summary>
        /// Simulates data retrieval from a repository
        /// </summary>
        /// <returns>List of strings</returns>
        private List<string> GetData()
        {
            repositoryData = new List<string>()
            {
                "Hello",
                "world"
            };
            return repositoryData;
        }

        /// <summary>
        /// Concatenate the information from the list into a fully formed sentence.
        /// </summary>
        /// <returns>A string</returns>
        private string ConcatenateData(List<string> dataList)
        {
            string importantInfo = dataList.ElementAt(0) + ", " + dataList.ElementAt(1) + "!";
            return importantInfo;
        }
    }
}

Se:

Slutligen kan View byggas. Det finns inget som behöver läggas till koden bakom för detta exempel, även om det kan variera beroende på applikationens behov. Det finns emellertid några rader som läggs till i XAML. Window behöver en referens till namnutrymmet ViewModel . Detta mappas till XAML-namnområdet xmlns:vm="clr-namespace:MyMVVMProject.ViewModel" . Därefter behöver fönstret en DataContext . Detta är inställt på <vm:HelloWorldViewModel/> . Nu kan etiketten (eller kontrollen du väljer) läggas till i fönstret. Nyckelpunkten i detta skede är att se till att du ställer in bindningen till egenskapen för ViewModel som du vill visa som etikettinnehåll. I det här fallet är det {Binding HelloString} .

Det är viktigt att binda till fastigheten och inte till fältet, eftersom i det senare fallet inte vyn får meddelandet om att värdet har ändrats, eftersom OnPropertyChanged() bara höjer PropertyChangedEvent på fastigheten och inte på fält.

<Window x:Class="MyMVVMProject.View.HelloWorldView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyMVVMProject.View"
        xmlns:vm="clr-namespace:MyMVVMProject.ViewModel"
        mc:Ignorable="d"
        Title="HelloWorldView" Height="300" Width="300">
    <Window.DataContext>
        <vm:HelloWorldViewModel/>
    </Window.DataContext>
    <Grid>
        <Label x:Name="label" FontSize="30" Content="{Binding HelloString}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow