Model-View-ViewModel maestro detalle (II)


Finalmente para implementar el borrado de una “fila” de un detalle, he implementado una nueva clase MasterDetailViewModel, que deriva de la clase ViewModel que ya tenia implementada.

Las vistas en las que vayan a ser maestro-detalle deberán implementar el ViewMode derivando de esta clase.

La clase tiene dos propiedades nuevas

· CurrentDetailName. Que indica el nombre del detalle que está activo en la vista ( deberá coincidir con el nombre de una propiedad de la entidad asociada al ViewModel.

· CurrentItem. Que tiene el objeto que esta actualmente seleccionado en el detalle.

   1: public string CurrentDetailName
   2: {
   3:     get { return this.currentDetailName; }
   4:     set
   5:     {
   6:         if (this.currentDetailName != value)
   7:         {
   8:             this.currentDetailName = value;
   9:             this.UpdateAllowedUserActions();
  10:         }
  11:     }
  12: }
  13:  
  14: public object CurrentItem
  15: {
  16:     get { return this.currentItem; }
  17:     set 
  18:     {
  19:         if (this.currentItem != value)
  20:         {
  21:             this.currentItem = value;
  22:             this.UpdateAllowedUserActions();
  23:         }
  24:     }
  25: }

Además sobreescribe dos métodos de ViewModel, para poder activar el botón de borrar de la barra de herramientas cuando estamos en edición y hay un detalle activo y otro para realizar el borrado.

   1: protected override bool CanDelete(object obj)
   2: {
   3:     bool canDelete = false;
   4:  
   5:     if (this.ViewModelState == ViewModelStateType.Default)
   6:     {
   7:         canDelete = base.CanAddNew(obj);
   8:     }
   9:     else
  10:     {
  11:         canDelete = (this.DeleteCommand.IsActive && 
  12:             !String.IsNullOrEmpty(this.CurrentDetailName) &&
  13:             this.CurrentItem != null);
  14:     }
  15:  
  16:     return canDelete;
  17: }
  18:  
  19: protected override void Delete(object obj)
  20: {
  21:     if (this.ViewModelState == ViewModelStateType.Default)
  22:     {
  23:         base.Delete(obj);
  24:     }
  25:     else
  26:     {
  27:         // Get the detail property info
  28:         PropertyInfo pi = this.DataModel.GetType().GetProperty(currentDetailName);
  29:         Debug.Assert(pi != null, String.Format("Detail {0} not found", currentDetailName));
  30:  
  31:         // Get the detail property value
  32:         object detail = pi.GetValue(this.DataModel, null);
  33:         Debug.Assert(pi != null, String.Format("Detail {0} not found", currentDetailName));
  34:         Debug.Assert(detail is IBindingList, String.Format("Detail {0} doesn't implement IBindingList", currentDetailName));
  35:  
  36:         IBindingList detailList = (IBindingList)detail;
  37:  
  38:         // Add a new entity to the detail object and set it as the current item
  39:         detailList.Remove(this.CurrentItem);
  40:     }
  41: }

En mi caso el detalle se va a mostrar siempre en un Grid, que, por el momento al menos, es la versión Express de el DataGrid de Xceed.

La solución es la más sencilla y posiblemente no es la ideal, pero hasta que encuentre una mejor me vale.

Por el momento sólo tiene 2 pegas.

1. Que necesita código en la vista para actualizar el nombre del detalle que está activo, por ejemplo:

   1: private void DataGridCambios_IsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
   2: {
   3:     if (Convert.ToBoolean(e.NewValue))
   4:     {
   5:         this.ViewModel.CurrentDetailName = "Cambios";
   6:     }
   7:     else
   8:     {
   9:         this.ViewModel.CurrentDetailName = "";
  10:     }
  11: }

2. Que al realizar el borrado el Grid está perdiendo el foco, cosa que resulta bastante molesta, tendré que ver si tengo alguna forma de solventarlo jejeje


Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s