I am writing a custom drop down list. I want to make it reusable (obviously), so I have a method PopulateList
. I can populate list in two ways though. First, is passing a list or an array of strings to PopulateList
. But I almost never want to select a string, right? Most of the time it's some complex objects. For example, say I have a class Dog
with two properties, Name
and Breed
. I want to show a drop down list with the names of the dogs. I can do listOfDogs.Select(x => x.Name).ToList()
and there I have it, a list of dogs that I can pass to PopulateList
. Now, since those are strings and my dropdown doesn't know about the objects themselves, when it will raise ItemSelected
event, it won't be able to say which object was selected, but rather which string, and I will have to do the mapping on the handling side. And that's okay, but that mapping part is kinda ugly.
The second way is doing this:
void PopulateList<T>(List<T> list, Func<T, string> selector )
{
var stringValues = list.Select(selector).ToList();
...
}
and using it like this:
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);
This way, dropdown won't care what kind of objects it is dealing with and will be able to know which object was selected and I will be able to beautifully wrap it in EventArgs
and pass it to the event handler.
My question is, what are the advantages of using the second approach? Is it unnecessary complexity?
EDIT:
I ended up implementing it like this:
async Task<T> PopupSelect<T>(string title, List<T> objects, Func<T, string> selector, bool hasDefault, T defaultObject = default(T))
It is very easy to use. For example:
_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);
new dog { id = "12345", name="nancy" }