Introduzione
Ne avevo parlato un po' 
di tempo fa qua sul mio blog. Se nel nostro domain model abbiamo creato una 
custom collection e poi vogliamo bindarla su una 
DataGridView, tale collection deve implementare l'interfaccia ITypedList. Questa 
interfaccia è di per sè abbastanza semplice: richiede l'implementazione di due 
soli metodi pubblici (GetItemProperties e GetListName). In pratica, il 
primo metodo ritorna un oggetto PropertyDescriptorCollection che rappresenta 
l'elenco delle proprietà che vogliamo bindare come colonne sulla DataGridView. Il secondo metodo ritorna una banale 
stringa con il nome della lista.
Facciamo un esempio pratico. Il class designer vale in questo caso molto più 
di mille parole:

Come è facilmente intuibile, la classe HockeyPlayer rappresenta un giocatore 
di hockey (nome, numero di maglia, peso, altezza ed elenco di falli subiti 
durante una partita). La classe Fault è il singolo fallo (tipo di fallo e quando 
è avvenuto). Poi esiste la classe FaultsCollection che non fa altro che 
ereditare direttamente da BindingList<Fault>. Se vogliamo 
bindare questa collection ad una DataGridView, dobbiamo utilizzare l'interfaccia 
ITypedList per intercettare il binding e specificare quali proprietà 
vogliamo ed in quale ordine. In questo caso è piuttosto semplice, perchè le 
proprietà sono solamente due, ma il problema c'è comunque e volevo 
risolverlo in un modo più elegante. Mi sono posto innanzitutto le seguenti 
domande:
  - Non è assolutamente corretto che io come sviluppatore debba decidere 
  durante lo sviluppo quali siano le colonne da far vedere, ed in quale ordine. 
  L'utente potrebbe voler personalizzare la vista, potrebbe riordinare le 
  colonne
- Non è assolutamente corretto che un business object debba sapere come 
  mostrarsi. Mi piacerebbe quindi che ad ogni binding di FaultsCollection, tale 
  classe richieda una sorta di Default View ad un'altra classe gemella, che 
  invece implementa tutta la logica necessaria
- Mi piacerebbe che le informazioni sul binding vengano persistite in 
  qualche modo, ad esempio su file. In questo modo, io decido in fase di 
  sviluppo la vista standard, ma se poi l'utente me la cambia (re-ordering delle 
  colonne sulla DataGridView) io devo accorgermene, salvare il tutto e 
  riprendere successivamente
Tutte queste domande mi hanno portato a creare una piccola soluzione che 
voglio proporre sul mio blog.
Come ho risolto il mio piccolo problema
Innanzitutto, 
l'abbiamo detto prima. La classe FaultsCollection deve implementare 
ITypedList.
using System;
using System.ComponentModel;
namespace DataBindingSample
{
    public class FaultsCollection : BindingList<Fault>, ITypedList
    {
        #region ITypedList
        public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
        {
            // ritorno un 
oggetto 
PropertyDescriptorCollection
        }
        public string GetListName(PropertyDescriptor[] listAccessors)
        {
            // ritorno 
"FaultsCollection"
        }
        #endregion
    }
}
Quando viene chiamato uno dei due metodi previsti dall'interfaccia, 
non faccio altro che delegare un'altra classe allo scopo. Questa altra classe si 
chiama FaultsCollectionDefaultView e dispone di due metodi statici che non fanno 
altro che mappare GetItemProperties e GetListName. Il codice è riportato qui 
sotto.
public static class FaultCollectionDefaultView
{
    public static PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
    {
        Type tp = typeof(Fault);
        PropertyDescriptorCollection m_OriginalList = TypeDescriptor.GetProperties(tp);
        PropertyDescriptorCollection m_SortedList = m_OriginalList.Sort(new string[] { "Motivo" });
        m_SortedList.RemoveAt(2);
        return (m_SortedList);
    }
    public static string GetListName(PropertyDescriptor[] listAccessors)
    {
        return "FaultsCollection";
    }
}
Il metodo GetItemProperties ottiene innanzitutto l'elenco delle 
property esposte dal singolo oggetto Fault: tale elenco viene gestito da 
m_OriginalList. Poi viene creato l'elenco vero e proprio che verrà utilizzato 
per il binding, usando solo la proprietà Motivo e rimuovendo la proprietà ID che 
non voglio mostrare mai all'utente finale.
In questo modo, non sarà direttamente la classe FaultsCollection a contenere 
queste codice, ma una classe gemella che invece contiene tutta la logica che 
serve per descrivere come una certa custom collection deve mostrarsi su 
una DataGridView.
Prossimo passo? Persistere su un file!
Il passo 
successivo dovrebbe migliorare in prestazioni ed in user-experience. L'idea è 
quella di andare a leggere su un file XML l'elenco delle properties da bindare, 
un elenco che potrebbe quindi anche esprimere direttamente l'ordine esatto di 
default. Invece di usare il metodo statico GetProperties di TypeDescriptor per ottenere un elenco preliminare dal 
quale poi togliere quello che non mi serve e riordinare, potrei direttamente 
andare a leggere su file le informazioni di binding.
In questo modo, inoltre, se l'utente finale riordina le colonne sulla 
DataGridView, non farei altro che persistere le nuove informazioni, per 
mantenerle tra una sessione di lavoro e l'altra. Non è solo una soluzione 
tecnica, ma anche una soluzione di design: non mi sembrava corretto che un 
oggetto venisse farcito di troppe responsabilità, delegando invece ad altri 
oggetti i relativi compiti.