tags:

views:

32

answers:

3

So I got this crazy idea I could make make something cool work. I got tired of new selectlist(item, "blah", "blahblah") so I started writing an extension method (trying to get it more strongly typed) something like this ...

var selectList = projects.ToSelectList(p =>p.ProjectID, p =>p.ProjectName);

the extension method goes a little like this

public static SelectList ToSelectList<T>(this IEnumerable<T> item, 
                           Expression<Func<T, string>> textName, 
                           Expression<Func<T, string>> valueProperty)
    {
        //do cool stuff
        return new SelectList(items, dataTextField, dataValueField);
    }

What I need to get to is the reflection properties so I can grab the value and grab the name. Any ideas onhow I can do that? Any thoughts on doing this more better/easier? I've done this before but for the life of me I can't remember how I did it.

Edit this needed some clarification. I copied some code that was in-flight and not refined, so I've updated that code to reflect the more correct criteria.

+5  A: 

I don't see why you have to use Reflection to do this.

public static SelectList ToSelectListItem<T>(this IEnumerable<T> items, 
    Func<T, string> textName, Func<T, string> valueProperty) {
    {
    return new SelectList(items
            .Select(i => new SelectListItem {Text = textName(i), Value = valueProperty(i)}));
    }
}

should would work, but I don't have the MVC dll on the current machine.

Yuriy Faktorovich
A: 

I originally tried your idea as well when I started with MVC but then I realized that some fields I wanted to format in a certain way and what about when an item is supposed to be selected by default. After handling all of that I realized it would be clearer to just write a one line LAMDA expression.

So now I usually just do a LAMDA expression to generate my SelectListItem collection.

<b>Screener: </b><%= Html.DropDownList("ScreenerOI", Model.Screeners.Select(p=>new SelectListItem() { Text = p.firstName + " " + p.lastName, Value = p.OI.ToString() })) %>

<b>Open Time: </b>
                <%= Html.DropDownListFor(c => c.OpenTime, Model.HoursInDay.Select(p => new SelectListItem() { Text = p != null ? DateTime.Now.Date.Add(p.Value).ToString("h:mm tt") : "Clear Time", Value = p != null ? p.ToString() : "", Selected = Model.OpenTime == p }).ToList())%>

It seems like this is just as clear as to what is going on as what your idea is.

Another Example

 <b>Screener Status: </b>
                <%= Html.DropDownListFor(c => c.InfoStatusOI, Model.InfoStatuses.Select(p => new SelectListItem() { Text = p != null ? p.Status.ToString() : "", Value = p != null ? p.OI.ToString() : "", Selected = p != null && Model.InfoStatusOI == p.OI }).ToList())%>
Paul Mendoza
A: 

This needs cleaned and tested for things like a zero count of the items, but here's the end result.

public static SelectList ToSelectList<T>(this IEnumerable<T> items, Expression<Func<T, object >> textName, Expression<Func<T, object >> valueProperty)
        {
            var dataTextField = textName.Body.ToString().Split('.')[1];
            var dataValueField = valueProperty.Body.ToString().Split('.')[1];
            return new SelectList(items, dataTextField, dataValueField);
        }
jeriley