Tal vez aquí ya es una pregunta, pero no lo encontré.¿Suscribirse a PropertyChanged o a una llamada de método de adición en setter?
Tengo la aplicación MVVM, y en mi ViewModel
tengo que hacer algunas acciones adicionales sobre los cambios de algunas propiedades (por ejemplo, si View
las cambia). ¿Qué enfoque es mejor en tu mente y por qué?
primero - Añadir AdditionalAction
llamada a Setter
public class ViewModel: INotifyPropertyChanged
{
private int _MyProperty;
public int MyProperty
{
get { return _MyProperty; }
set
{
if (_MyProperty == value) return;
_MyProperty = value;
RaisePropertyChanged(() => MyProperty);
// --- ADDITIONAL CODE ---
AdditionalAction();
}
}
}
segundo - Auto-suscribirse a INotifyPropertyChanged
public class ViewModel: INotifyPropertyChanged
{
public ViewModel()
{
// --- ADDITIONAL CODE ---
PropertyChanged += OnPropertyChanged;
}
private int _MyProperty;
public int MyProperty
{
get { return _MyProperty; }
set
{
if (_MyProperty == value) return;
_MyProperty = value;
RaisePropertyChanged(() => MyProperty);
}
}
void PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// --- ADDITIONAL CODE ---
if (e.PropertyName == "MyProperty")
AdditionalAction();
}
}
Imagínese, que yo no tengo problema de rendimiento o 10'000 objetos Es solo View y ViewModel. ¿Qué es mejor? El primer código es "más pequeño" y tiene menos sobrecarga, pero el segundo (en mi opinión) es más claro y puedo usar fragmentos de código para el código de propiedades de autogeneración. Aún más - en el segundo caso Puedo escribir en el controlador de eventos algo como:
On.PropertyChanged(e, p => p.MyProperty, AdditionalAction);
donde On
es la clase-ayudante.
Entonces, ¿qué es lo que tiene en mente y por qué?
Actualizado:
OK, parece que he encontrado todavía un enfoque:
tercero - añadir "punto de extensión" en RaisePropertyChanged:
public class NotificationObject : INotifyPropertyChanged
{
void RaisePropertyChanged(Expression<...> property)
{
// ... Raise PropertyChanged event
if (PropertyChanged != null)
// blah-blah
// Call extension point
OnPropertyChanged(property.Name);
}
public virtual OnPropertyChanged(string propertyName)
{
}
}
public class ViewModel: NotificationObject
{
private int _MyProperty;
public int MyProperty
{
get { return _MyProperty; }
set
{
if (_MyProperty == value) return;
_MyProperty = value;
RaisePropertyChanged(() => MyProperty);
}
}
override OnPropertyChanged(string propertyName)
{
if (propertyName == "MyProperty")
AdditionalAction();
}
}
esta manera no usamos evento, pero todas las "acciones adicionales" se invocan desde el mismo "punto de extensión". ¿Es mejor un "lugar para todas las acciones adicionales" que un "flujo de trabajo no transparente"?
http://tergiver.wordpress.com/2011/01/20/self-subscription-is-asinine/ – Tergiver
sidenote: considere el uso de un método de ayuda para poner las tres líneas en colocador de sus propiedades a uno, devolviendo un booleano si la propiedad cambió. Más corto y sin duplicación. ej. 'if (RaisePropertyChanged (ref _MyProperty, value, o => o.MyProperty)) AdditionalAction();' – stijn
@Tergiver ¿Cuál es la diferencia entre tu camino y mi 2da manera? Son lo mismo: escribe código adicional no en el "setter" pero en el "controlador de eventos". El método 'OnXXX' desde este punto de vista es lo mismo que la auto-suscripción al evento. Entonces, desde su punto de vista, mi pregunta es: "¿Es mejor llamar a 'AdditionalAction' desde setter o desde el método OnPropertyChanged?" (incluso si no hay un método OnPropertyChanged en realidad) – chopikadze