Forse qui è già una domanda del genere, ma non l'ho trovata.Auto-sottoscrizione a PropertyChanged o metodo aggiuntivo call in setter?
Ho un'applicazione MVVM e nel mio ViewModel
Devo eseguire alcune azioni aggiuntive sulle modifiche di alcune proprietà (ad esempio, se View
le modifica). Quale approccio è migliore nella tua mente e perché?
1 ° - Aggiungi AdditionalAction
chiamata al 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();
}
}
}
2 ° - Auto-sottoscrivere 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();
}
}
Immaginate, che non ho problema di prestazioni o 10.000 oggetti. È solo View e ViewModel. Cos'è meglio? Il primo codice è "più piccolo" e ha meno spese generali, ma il secondo (a mio avviso) è più chiaro e posso usare i frammenti di codice per il codice delle proprietà di generazione automatica. Ancora più - nel 2 ° caso posso scrivere nel gestore di eventi qualcosa di simile:
On.PropertyChanged(e, p => p.MyProperty, AdditionalAction);
dove On
è di classe-helper.
Quindi, cosa c'è di meglio nella tua mente e perché?
aggiornamento:
OK, sembra che ho trovato ancora un approccio:
3 - aggiungere "punto di estensione" in 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();
}
}
In questo modo non usiamo l'evento, ma tutte le "azioni aggiuntive" sono chiamate dallo stesso "punto di estensione". "Un posto per tutte le azioni di addizione" è meglio di "un flusso di lavoro non trasparente"?
http://tergiver.wordpress.com/2011/01/20/self-subscription-is-asinine/ – Tergiver
sidenote: considerare l'utilizzo di un metodo di supporto per mettere le tre linee in setter dei vostri oggetti da uno, restituire un booleano se la proprietà è cambiata. Più breve e nessuna duplicazione. per esempio 'if (RaisePropertyChanged (ref _MyProperty, value, o => o.MyProperty)) AdditionalAction();' – stijn
@Tergiver quali sono le differenze tra la tua strada e la mia seconda via? Sono uguali: scrivi codice aggiuntivo non nel "setter" ma nel "gestore di eventi" - il metodo "OnXXX" da questo punto di vista è lo stesso dell'abbonamento automatico all'evento. Quindi, dal tuo punto di vista la mia domanda è: "È meglio chiamare' AdditionalAction' dal setter o dal metodo OnPropertyChanged? " (anche se in realtà non esiste il metodo OnPropertyChanged) – chopikadze