2011-05-20 12 views
6

Estoy trabajando en una aplicación de Silverlight utilizando V3 SP1 de MVVM Light Toolkit.Notificar que todas las propiedades han cambiado en ViewModel

Mi aplicación es totalmente francesa/inglesa. Todos los elementos de la interfaz de usuario (botones, etiquetas, etc.) y todos los datos (modelos). Necesito el cambio de idioma dinámico y esto está completamente implementado y funciona con cualquier cosa que provenga de un archivo de recursos. Lo que estoy luchando es con ViewModels.

Los modelos tienen propiedades específicas del lenguaje (DescriptionEn, DescriptionFr) y una propiedad adicional llamada LocalizedDescription que utiliza la cultura actual para devolver la llamada a la propiedad específica del idioma.

Cuando el idioma cambia (mediante un clic de botón) levanto y transmito (a través del Messenger) un evento de propiedad modificada.

En cada una de mis ViewModels, me registro para recibir el mensaje de cambio de propiedad para el intercambio de idiomas.

Quiero notificar a todas las propiedades del ViewModel que algo ha cambiado.

Desde: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx

The PropertyChanged event can indicate all properties on the object have changed by using either null or String.Empty as the property name in the PropertyChangedEventArgs.

Sin embargo, dado que el conjunto de herramientas abstrae la elevación del evento modificado con RaisePropertyChanged (...) No puedo conseguir que esto funcione. También he examinado el origen de los takeit y he descubierto que RaisePropertyChanged llama a VerifyPropertyName (..), que a su vez devuelve un error, ya que la propiedad no pertenece al ViewModel. También noté que el método VerifyPropertyName se atribuye con Conditional ("DEBUG"), pero incluso si elijo la configuración de Release, la ArgumentException ("Propiedad no encontrada") aún se genera.

¿Alguien sabe de una manera de hacer que esto funcione usando el kit de herramientas aparte de llamar manualmente a RaisePropertyChanged para cada propiedad del ViewModel?

Seguimiento:

Basado en el comentario de Simon, que intentó crear mi propia clase que se extiende ViewModelBase. Miré la fuente en CodePlex y decidí crear un único método llamado RaiseAllPropertyChanged(). Simplemente sería una copia de RaisePropertyChanged (string propertyName) pero sin el parámetro y sin la llamada a VerifyPropertyName (...). No puedo hacer que funcione. Esto es lo que tengo.

public class ViewModelBaseExtended : ViewModelBase 
{ 
    protected void RaiseAllPropertyChanged() 
    { 
     var handler = this.PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(String.Empty)); 
     } 
    } 
} 

Pero obtengo un error del compilador: The event 'GalaSoft.MvvmLight.ViewModelBase.PropertyChanged' can only appear on the left hand side of += or -=. Esta es una copia del código que se usa en ViewModelBase.

¿Alguien puede ofrecer algún consejo sobre cómo hacer que esto funcione?

Solución:

he copiado todo el código de ViewModelBase en una nueva clase. Luego agregué el método RaisePropertyChanged() mencionado anteriormente que ejemplifica la clase PropertyChangedEventArgs con String.Empty. Esta es ahora la nueva subclase para mis ViewModels.

¡Gracias de nuevo a Simon por liderar el camino!

+0

¿por qué se le notifica para todos modos? – Simon

+0

Notifico todas las propiedades porque necesito que vuelvan a leer sus datos debido a un cambio de idioma. Por ejemplo, tengo un ViewModel que tiene 10 propiedades. Esas propiedades son colecciones de datos que tienen descripciones en francés e inglés y se representan en tiempo de ejecución en el idioma actual. Cuando se cambia el idioma actual, necesito notificar todas las propiedades para que sus datos ahora se muestren en el nuevo idioma actual. Aunque, al implementar la solución anterior, todavía estoy luchando para obtener los datos para cambiar de idioma. Pero el problema de notificar a todos está resuelto. –

Respuesta

2

Desafortunadamente esto no es posible con el código base actual de MVVMLight

En el corto plazo su tiene 2 opciones

  1. usuario su propia clase base personalizado. Una clase base personalizada me refiero a "No heredar de la clase MVVMLight"

  2. Descargue y compile MVVMLight en modo Release. Esto forzará la exclusión del método "VerifyPropertyName". Por supuesto, entonces no obtiene el valor de las comprobaciones del nombre de la propiedad.

estoy seguro de Laurent Bugnion tendrá que esto esté arreglado pronto.

+0

He agregado una continuación a mi pregunta original tomando su sugerencia de una nueva clase base. ¿Alguna sugerencia? –

+0

@Vincenzo actualizo mi respuesta. no puede acceder a un evento en una clase base de esa manera. necesitas crear tu propia clase base personalizada desde cero. – Simon

+0

@Vincenzo ¿Estás en twitter? si es así, póngame en http://twitter.com/SimonCropp y podemos hablar de esto – Simon

1

Una solución a este problema más ligero habría sido para anular RaisePropertyChanged (cadena nombrePropiedad) en su clase:

protected override void RaisePropertyChanged(string propertyName) 
    { 
     if (propertyName != null) 
     { 
      base.RaisePropertyChanged(propertyName); 
     } 
     else 
     { 
      var handler = PropertyChangedHandler; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(null)); 
      } 

     } 
    } 
2

En caso de que usted está leyendo esto en 2016, puede utilizar ObservableObject y notifique que todos las propiedades han cambiado haciendo:

RaisePropertyChanged(string.Empty); 
Cuestiones relacionadas