Sto scrivendo un elenco a discesa personalizzato. Voglio renderlo riutilizzabile (ovviamente), quindi ho un metodo PopulateList
. Posso popolare la lista in due modi però. Innanzitutto, passa una lista o una matrice di stringhe a PopulateList
. Ma quasi mai non voglio selezionare una stringa , giusto? Il più delle volte si tratta di oggetti complessi. Ad esempio, supponiamo di avere una classe Dog
con due proprietà, Name
e Breed
. Voglio mostrare un elenco a discesa con i nomi dei cani. Posso fare listOfDogs.Select(x => x.Name).ToList()
e lì ce l'ho, una lista di cani che posso passare a PopulateList
. Ora, dal momento che quelle sono stringhe e il mio menu a discesa non conosce gli oggetti stessi, quando aumenterà l'evento ItemSelected
, non sarà in grado di dire quale oggetto è stato selezionato, ma piuttosto quale string e dovrò fare il mapping sul lato della gestione. E va bene, ma quella parte di mappatura è piuttosto brutta.
Il secondo modo è questo:
void PopulateList<T>(List<T> list, Func<T, string> selector )
{
var stringValues = list.Select(selector).ToList();
...
}
e usarlo in questo modo:
var list = new List<Dog>
{
new Dog {Breed = "German Shepard", Name = "Nancy"},
new Dog {Breed = "Collie", Name = "Stacy"} // weird name choices, I know
};
PopulateList(list, dog => dog.Name);
In questo modo, il menu a discesa non si preoccuperà di quale tipo di oggetti ha a che fare e sarà in grado di sapere quale oggetto è stato selezionato e io sarò in grado di avvolgerlo magnificamente in EventArgs
e passalo al gestore dell'evento.
La mia domanda è: quali sono i vantaggi dell'utilizzo del secondo approccio? È una complessità inutile?
EDIT:
Ho finito per implementarlo in questo modo:
async Task<T> PopupSelect<T>(string title, List<T> objects, Func<T, string> selector, bool hasDefault, T defaultObject = default(T))
È molto facile da usare. Ad esempio:
_button.Clicked += async delegate
{
var list = new List<Tuple<string, string>>()
{
Tuple.Create("asdf", "Dog"),
Tuple.Create("a", "Cat"),
Tuple.Create("d", "Mouse"),
Tuple.Create("e", "Rat"),
Tuple.Create("r", "Hamster"),
Tuple.Create("2", "Elephant"),
Tuple.Create("344", "Lion"),
Tuple.Create("ascv", "Tiger"),
Tuple.Create("vv", "Buffalo"),
};
var selected = await PopupSelect("Select a pet", list, s => s, true, list[5]);
if (selected == null)
Debug.WriteLine("Sorry, no value was selected");
else
Debug.WriteLine(selected.Item2);