2010-01-26 9 views
9

Estoy usando el wpf toolkit datagrid para mostrar una colección observable de AccountViewModels.Cómo mantener colecciones de viewmodels y modelos sincronizados

El problema es que cuando elimino una cuenta de la grilla, quiero que se elimine de ObservableCollection para dar al usuario comentarios visuales, pero quiero que la lista subyacente de modelos de Cuenta permanezca igual, solo con un 'IsDeleted 'bandera establecida en el modelo de Cuenta.

Luego, cuando se confirman los cambios, mi servicio sabe qué cuentas agregar/actualizar o eliminar en la base de datos.

Im suscripción al evento CollectionChanged:

AccountViewModels.CollectionChanged += AccountsChanged; 

, y luego poner isDeleted modelo de la bandera de los ViewModels' en true siempre se quita algo:

private void AccountsChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (e.NewItems != null) 
     { 
      foreach (AccountViewModel model in e.NewItems) 
      { 
       model.PropertyChanged += accountPropertyChanged; 
       model.Account.IsNew = true; 
      } 
     } 
     if (e.OldItems != null) 
     { 

      foreach (AccountViewModel model in e.OldItems) 
      { 
       model.PropertyChanged -= accountPropertyChanged; 
       model.Account.IsDeleted = true; 
      } 
     } 
    } 

pero obviamente esto entonces lo quita de la observables colección. Entonces, cuando llegue el momento de confirmar los cambios, no habrá cuentas con el indicador IsDeleted establecido. es decir, ya se habrán eliminado.

foreach (AccountViewModel acc in m_ViewModel.AccountViewModels) 
     { 
      WorkItem workItem = null; 
      if(acc.Account.IsNew) 
       workItem = new WorkItem("Saving new account: " + acc.AccountName, "Saving new account to the database",() => Service.AddAccount(acc.Account)); 
      else if (acc.Account.IsDeleted) 
       workItem = new WorkItem("Removing account: " + acc.AccountName, "Setting account inactive in the database",() => Service.RemoveAccount(acc.Account)); 
      else if(acc.Account.IsDirty) 
       workItem = new WorkItem("Updating account: " + acc.AccountName, "Updating account in the database",() => Service.UpdateAccount(acc.Account)); 

      workItems.Add(workItem); 

     } 

lo hace significa esto que necesito para mantener dos listas, una lista de los modelos de la cuenta y el otro una colección observable de accountviewmodels? Esto simplemente parece desagradable y debe haber una mejor manera de hacerlo.

Respuesta

3

No creo que pueda hacer esto mejor con ObservableCollection, ya que esa clase tiene su propia lista interna de objetos.

Sin embargo, si implementa una Colección personalizada que implementa INotifyCollectionChanged e INotifyPropertyChanged, puede dejar que se ajuste y filtre su colección de origen.

Podría filtrar en el indicador IsDeleted para que estos no sean visibles.

Siempre que un usuario elimine un elemento, puede modificar el Modelo de dominio directamente, estableciendo el indicador IsDeleted en verdadero. Sin embargo, aún necesitará un mecanismo de evento para poder plantear los eventos apropiados, pero con ese enfoque, solo tiene una única colección de elementos.

La colección personalizada sería simplemente una proyección sobre el modelo de dominio, con eventos añadidos.

+0

Si voy esta ruta, ¿Cómo capturo el caso de cambio de propiedad cuando uno de los campos en mi modelo es editado en la cuadrícula. Realmente no quiero que mi modelo de dominio tenga que implementar INotifyPropertyChanged, esto es algo que mi viewmodel estaba haciendo previamente. – cjroebuck

+0

Eso es lo que quise decir cuando dije que necesitas tener * algún * mecanismo de evento en su lugar. O bien, puede generar un evento desde su Modelo de dominio (no es necesario que sea INotifiedPropertyChanged - podría ser un evento personalizado en su lugar), o necesita notificar explícitamente a Projecting Collection sobre el cambio para que pueda generar los eventos correctos. Una tercera opción es tener el sondeo Projecting Collection para los cambios en el modelo subyacente, pero esa ruta está llena de peligro ... –

Cuestiones relacionadas