Anonymous types e ListBox: un’accoppiata da evitare

Print Content | More

Recentemente ho aiutato uno sviluppatore che aveva un problema con un’applicazione Windows Phone: lo scenario era quella di una ListBox in binding con una collezione di oggetti. La particolarità è che il tipo di questi oggetti era anonimo. Con le ultime versioni del framework viene data infatti la possibilità di generare tipi “al volo”, senza la necessità di creare una classe ad hoc.

Ecco un esempio di dichiarazione di un anonymous type:

var person = new
{
    Name = "Matteo",
    Surname = "Pagani"
};

Come potete notare, non è specificato il tipo dell’oggetto, proprio perchè viene creato in tempo reale dal compilatore. L’Intellisense di Visual Studio è poi abbastanza intelligente da ricordarsi la definizione dell’anonymous type, perciò se utilizzassimo successivamente l’oggetto person avremmo a disposizione le proprietà Name e Surname esattamente come se si trattasse di una classe tradizionale.

Gli anonymouse type sono molto utili quando dobbiamo fare delle operazioni sui nostri oggetti per ottenere dei risultati temporanei, che non abbiamo bisogno di mantenere e quindi non giustificherebbero la necessità di avere un tipo dedicato.

Ma torniamo al problema dello sviluppatore: quello che lui faceva nella sua applicazione era popolare un ListBox con una collezione di tipo List, la quale conteneva una serie di oggetti di tipo anonimo, come risultato di una query LINQ su un database SQL CE.

Ecco un esempio:

var result = persons.Select(x => new
                                     {
                                         Name = x.Name,
                                         Surname = x.Surname,
                                     });
PersonsList.ItemsSource = result;

Il problema è che, in fase di esecuzione, la ListBox non mostrava alcun risultato: in più, la Output Window di Visual Studio mostrava una lunga serie di errori di questo tipo

System.Windows.Data Error: 12 : Cannot get 'First' value (type 'String') from '' (type '<>f__AnonymousType0`2')”).

Avevo già il sospetto che anonymous type e il binding non andassero molto d’accordo, ma una ricerca su Internet me ne ha dato la conferma e la motivazione tecnica: come potete leggere qui, gli anonymous type vengono definiti come internal e, in Silverlight, non è possibile mettere in binding un controllo con una proprietà di tipo internal.

La soluzione è perciò molto semplice: occorre creare un tipo ad hoc ed usare una collezione di oggetti di quel tipo specifico. Nel nostro esempio, occorre creare una classe di tipo Person:

public class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
}

e trasformare l’operazione LINQ precedente in:

var result = persons.Select(x => new Person
                                     {
                                         Name = x.Name,
                                         Surname = x.Surname,
                                     });
PersonsList.ItemsSource = result;

A questo punto tutto funzionerà correttamente e la ListBox sarà correttamente popolata.


Windows Phone , Microsoft , Anonymous Type , ListBox

1 comments

Related Post

  1. #1 da Filippo Tuesday July 2012 alle 05:48

    sembra che invece sia possibile!
    http://wp7nugets.wordpress.com/2012/05/25/binding-to-anonymous-types/


(will not be published)
(es: http://www.mysite.com)