tutorial implementar español como beginner c# wpf mvvm viewmodel

c# - implementar - Cómo escribir "ViewModelBase" en MVVM(WPF)



wpf como implementar mvvm (5)

Soy bastante nuevo en el entorno de programación de WPF. Estoy tratando de escribir un programa usando el patrón de diseño de MVVM.

Hice algunos estudios y leí algunos artículos relacionados y muchas veces me encontré con esto llamado

ViewModelBase

Sé lo que es ... Pero, ¿puedo saber específicamente dónde debo comenzar para poder escribir mi propio ViewModelBase? Como ... Entender realmente lo que está pasando sin ser demasiado complicado. Gracias :)


Me gusta este BaseVewModel que le da un estilo agradable y limpio a sus modelos de vista. Vea las diversas comparaciones ''antes'' y ''después''. Por supuesto, nada es obligatorio: si no le gusta una característica que proporciona el modelo BaseView, entonces no la use. O modifíquelo porque tiene el código fuente. En particular, tenga en cuenta que hay tres formas diferentes de implementar propiedades con notificación de cambio: elija el nivel de sofisticación con el que usted entiende / se siente cómodo.


Tienes algún paquete nuget para implementar MVVM

  1. Luz MVVM
  2. MVVM Cross
  3. Prisma

Para mí, lo más fácil para un principiante es la luz MVVM porque proporciona una muestra de código.

Así que mejor es instalar este paquete Nuget, echar un vistazo al código generado y regresar a nosotros para obtener más explicaciones si lo necesita.


En la mayoría de los marcos MVVM, las clases base ViewModel en realidad contienen muy poco código, generalmente solo una implementación de INotifyPropertyChanged y algunas funciones auxiliares.

Eche un vistazo al código fuente de las clases ViewModelBase y ObservableObject de MVVM Light. ObservableObject es principalmente la implementación INotifyPropertyChanged, que utiliza una expresión lambda en lugar de "cadenas mágicas" para el nombre de la propiedad. ViewModelBase amplía ObservableObject y es principalmente un método de utilidad para determinar si se está ejecutando dentro del diseñador de Visual Studio.


Hay una buena discusión aquí: https://codereview.stackexchange.com/q/13823 sobre el tema. Tiene un buen enfoque al usar expresiones para que pueda obtener la seguridad de tipo al elevar las notificaciones de propiedad cambiada.


No vale la pena usar marcos MVVM si no sabes lo que sucede dentro.

Así que vamos paso a paso y construyamos su propia clase ViewModelBase.

  1. ViewModelBase es una clase común para todos sus modelos de vista. Así que pasemos toda la lógica común a esta clase.

  2. tus viewmodels deberían implementar INotifyPropertyChanged (¿entiendes por qué?)

    public abstract class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }

    el atributo [CallerMemberName] no es obligatorio, pero le permitirá escribir: OnPropertyChanged(); en lugar de OnPropertyChanged("SomeProperty"); , por lo que evitará la constante de cadena en su código. ejemplo:

    public string FirstName { set { _firtName = value; OnPropertyChanged(); //instead of OnPropertyChanged("FirstName") or OnPropertyChanged(nameof(FirstName)) } get{ return _firstName;} }

    Tenga en cuenta que OnPropertyChanged(() => SomeProperty) no es más recomendable, ya que tenemos el operador nameof en C # 6.

  3. Es práctica común, que implemente propiedades que llame a PropertyChanged así:

    public string FirstName { get { return _firstName; } set { SetProperty(ref _firstName, value); } }

    Definamos SetProperty en su viewmodelbase:

    protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "") { if (EqualityComparer<T>.Default.Equals(storage, value)) return false; storage = value; this.OnPropertyChanged(propertyName); return true; }

    simplemente activa el evento PropertyChanged cuando el valor de la propiedad cambia y devuelve verdadero. no activa el evento cuando el valor no ha cambiado y devuelve falso. La idea básica es que el método SetProperty es virtual y puede ampliarlo en una clase más concreta, por ejemplo, para activar la validación o llamando al evento PropertyChanging .

Esto es lindo. Esto es todo lo que su ViewModelBase debe contener en esta etapa. El resto depende de tu proyecto. Por ejemplo, su aplicación utiliza la navegación de la base de la página y ha escrito su propio NavigationService para manejar la navegación desde ViewModel. De modo que puede agregar la propiedad NavigationSerivce a su clase ViewModelBase, de modo que tendrá acceso a ella desde todos sus modelos de vista, si lo desea.

para obtener más reusabilidad y mantener SRP, tengo una clase llamada BindableBase que es prácticamente la implementación de INotifyPropertyChanged como lo hemos hecho aquí. Reutilizo esta clase en cada solución WPF / UWP / Silverligt / WindowsPhone, porque es universal.

Luego, en cada proyecto, creo una clase personalizada ViewModelBase derivada de BindableBase:

public abstract ViewModelBase : BindableBase { //project specific logic for all viewmodels. //E.g in this project I want to use EventAggregator heavily: public virtual IEventAggregator () => ServiceLocator.GetInstance<IEventAggregator>() }

si tengo una aplicación, que usa navegación basada en página, también especifico la clase base para los modelos de vista de página.

public abstract PageViewModelBase : ViewModelBase { //for example all my pages has title: public string Title {get; private set;} }

Podría tener otra clase para diálogos:

public abstract DialogViewModelBase : ViewModelBase { private bool? _dialogResult; public event EventHandler Closing; public string Title {get; private set;} public ObservableCollection<DialogButton> DialogButtons { get; } public bool? DialogResult { get { return _dialogResult; } set { SetProperty(ref _dialogResult, value); } } public void Close() { Closing?.Invoke(this, EventArgs.Empty); } }