Su MSDN Magazine di questo mese c'è un interessante articolo sulla ObservableCollection<T>, molto utile per il databinding e l'implementazione del pattern V-M-VM. Tutte cose arcinote, se non fosse per tre piccole chicche degne di nota (almeno per me):
- Viene rimarcato il fatto che la ObservableCollection<T> usa INotifyCollectionChanged per notificare che è stato aggiunto o tolto un elemento dalla collezione, e INotifyPropertyChanged per notificare che una proprietà della collezione è cambiata. E qui sta il punto: la collezione non notifica nulla se è cambiata una proprietà di uno degli elementi di tipo T facenti parte della collezione. Sono i singoli elementi che (se T implementa a sua volta INotifyPropertyChanged) notificheranno tale cambiamento.
- Per rispondere a tale notifica, occorre iterare la collezione e sottoscrivere la notifica dell'evento per ogni elemento della collezione. Qui di seguito un mini esempio, tratto dal quello contenuto nell'articolo, con la dichiarazione della classe, la sottoscrizione dell'evento e un metodo che usa Reflection per recuperare il nuovo valore della proprietà modificata che ha fatto scattare l'evento:
1: private ObservableCollection<Customer> customers
2: ...
3: foreach (Customer cust in customers)
4: {
5: cust.PropertyChanged += HandleCustomerPropertyChanged;
6: }
7: ...
8: private void HandleCustomerPropertyChanged(object sender, PropertyChangedEventArgs e)
9: {
10: string propName = e.PropertyName;
11: Customer cust = (Customer)sender;
12:
13: // PropertyChangedEventArgs non contiene alcuna informazione sul valore
14: // precedente ne su quello attuale delle proprietà modificata.
15: // Volendo, si può usare Reflection per ritrovare il valore attuale della proprietà,
16: // a partire dall'oggetto che ha generato l'evento e dal nome della proprietà
17: System.Reflection.PropertyInfo propInfo = typeof(Customer).GetProperty(propName);
18: object value = propInfo.GetValue(cust, null);
19:
20: MessageBox.Show(String.Format("Hai cambiato la propietà '{0}' al valore '{1}'", propName, value));
21: }
- Infine, pur avendo letto qualche libro e un bel po' di esempi, non mi ero mai imbattuto in un caso di binding con un un oggetto istanziato nel codice (senza impostare il classico DataContext). Tanto da aver pensato che non fosse possibile. Invece è semplicissimo e così banale da aver confermato la mia scarsissima autostima: ho il cervello di un bradipo!
Comunque, siccome riscrivere il codice è un buon esercizio per imparare, ho fatto il porting del codice da VisualBasic a C#, e già che c'ero ho cambiato i nomi dei customers: ogni riferimento a persone realmente esistenti è del tutto casuale!
Chi desidera può scaricare i sorgenti del porting dal mio SkyDrive