Buscar..


Observaciones

Esta sección proporciona una descripción general de qué es mvvm y por qué un desarrollador puede querer usarlo.

También debe mencionar cualquier tema grande dentro de mvvm, y vincular a los temas relacionados. Dado que la Documentación para mvvm es nueva, es posible que deba crear versiones iniciales de esos temas relacionados.

C # MVVM Resumen y ejemplo completo

Resumen:

MVVM es un patrón arquitectónico que está representado por tres componentes distintos, Model , View y ViewModel . Para entender estas tres capas, es necesario definir brevemente cada una, seguida de una explicación de cómo funcionan juntas.

El modelo es la capa que impulsa la lógica empresarial. Recupera y almacena información de cualquier fuente de datos para el consumo de ViewModel .

ViewModel es la capa que actúa como un puente entre la Vista y el Modelo . Puede o no transformar los datos sin procesar del modelo en un formato presentable para la vista . Una transformación de ejemplo sería: un indicador booleano desde el modelo a la cadena de 'Verdadero' o 'Falso' para la vista.

View es la capa que representa la interfaz del software (es decir, la GUI). Su función es mostrar la información de ViewModel al usuario y comunicar los cambios de la información a ViewModel .

Estos tres componentes trabajan juntos al hacer referencia entre sí de la siguiente manera:

  • La Vista hace referencia al ViewModel .
  • El ViewModel hace referencia al modelo .

Es importante tener en cuenta que View y ViewModel son capaces de comunicaciones de dos vías conocidas como enlaces de datos .

Un ingrediente importante para la comunicación bidireccional (enlace de datos) es la interfaz INotifyPropertyChanged .

Al utilizar este mecanismo, la Vista puede modificar los datos en ViewModel a través de la entrada del usuario, y ViewModel puede actualizar la Vista con datos que pueden haber sido actualizados a través de procesos en el Modelo o con datos actualizados del repositorio.

La arquitectura MVVM pone un gran énfasis en la Separación de Preocupaciones para cada una de estas capas. La separación de las capas nos beneficia como:

  • Modularidad: la implementación interna de cada capa se puede cambiar o intercambiar sin afectar a las otras.
  • Mayor capacidad de prueba : cada capa puede probarse por unidad con datos falsos, lo que no es posible si el código de ViewModel está escrito en el Código de Detrás de la Vista .

La construcción:

Crear un nuevo proyecto de aplicación WPF Crear un nuevo proyecto de aplicación WPF

Cree tres nuevas carpetas en su solución: Model , ViewModel y View , y elimine MainWindow.xaml original, solo para comenzar de nuevo.

Crea 3 nuevas carpetas en tu solución

Cree tres nuevos elementos, cada uno correspondiente a una capa separada:

  • Haga clic con el botón derecho en la carpeta Modelo y agregue un elemento de Clase llamado HelloWorldModel.cs .
  • Haga clic con el botón derecho en la carpeta ViewModel y agregue un elemento de clase llamado HelloWorldViewModel.cs .
  • Haga clic con el botón derecho en la carpeta Ver y agregue un elemento de Ventana (WPF) llamado HelloWorldView.xaml .

Añadir los tres elementos.

Alterar App.xaml para apuntar a la nueva Vista

<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:

Comience con la construcción de ViewModel primero. La clase debe implementar la interfaz INotifyPropertyChanged , declarar un evento PropertyChangedEventHandler y crear un método para generar el evento (fuente: MSDN: Cómo implementar la notificación de cambio de propiedad ). A continuación, declarar un campo y una propiedad correspondiente, asegurándose de llamar a la OnPropertyChanged() método en el alojamiento set de acceso. El constructor en el ejemplo a continuación se usa para demostrar que el modelo proporciona los datos a 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;
        }
    }
}

Modelo:

A continuación, construir el modelo . Como se indicó anteriormente, el modelo proporciona datos para ViewModel extrayéndolos de un repositorio (y también lo regresa al repositorio para guardarlo). Esto se demuestra a continuación con el método GetData() , que devolverá una List<string> simple List<string> . La lógica de negocios también se aplica en esta capa, y puede verse en el método ConcatenateData() . Este método construye la frase "¡Hola, mundo!" De la List<string> que se devolvió previamente de nuestro "repositorio".

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

Ver:

Finalmente, la vista se puede construir. No hay nada que deba agregarse al código detrás de este ejemplo, aunque esto puede variar según las necesidades de la aplicación. Sin embargo, hay algunas líneas agregadas al XAML. La Window necesita una referencia al espacio de nombres de ViewModel . Esto se asigna al espacio de nombres XAML xmlns:vm="clr-namespace:MyMVVMProject.ViewModel" . A continuación, la ventana necesita un DataContext . Esto se establece en <vm:HelloWorldViewModel/> . Ahora la etiqueta (o el control de su elección) se puede agregar a la ventana. El punto clave en esta etapa es asegurar que se establece la unión a la propiedad del modelo de vista que desea mostrar como el contenido de la etiqueta. En este caso, es {Binding HelloString} .

Es importante enlazar a la propiedad, y no al campo, ya que en este último caso la Vista no recibirá la notificación de que el valor cambió, ya que el método OnPropertyChanged() solo elevará el PropertyChangedEvent en la propiedad, y no en el campo.

<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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow