2017-02-01 14 views
0

我發現this文章顯示如何將List轉換爲IEnumerable。有人可以向我解釋,如果有可能將它轉換成可以被許多列表使用的通用函數?使用TModel將通用函數轉換爲IEnumerable <SelectListItem>

舉例來說,我有一個

public class City 
{ 
    public int CityId { get; set; } 
    public string CityName { get; set; } 
} 
public class State 
{ 
    public int StateId { get; set; } 
    public string StateName { get; set; } 
    public string StateAbbreviation { get; set; } 
} 

然後,我有這兩個名單,我想顯示一個下拉菜單:

List<City> cities 
List<State> states 

我就可以建立做類似的東西2種不同的方法這個,但是我必須複製/粘貼這個代碼到多個列表中,這不是我想要的。

public static IEnumerable<SelectListItem> GetCitiesSelectList() 
{ 
    IEnumerable<SelectListItem> cityList = GetCities().Select(x => new SelectListItem() { Text = x.CityName, Value = x.CityId.ToString() }); 
    return qList; 
} 

什麼我不知道是如果有一些與此類似,但能夠在任何類型的列表來傳遞,並通過在列表中文字與價值?我知道你可以用TModel做點什麼,但我不完全理解它,並希望有人能把我推向正確的方向。

+0

爲什麼Statename的,CITYNAME?爲什麼不只是名字 – Peru

+0

爲了清楚起見,因爲它只是一個例子。 –

+0

用一些代碼片段更新了我的答案http://stackoverflow.com/a/41990164/1481690 – Peru

回答

0

@ miguelerm的回答是可靠的。但是,如果您使用的字符串常量,性質是不舒服,你可以爲這種轉換創建一個擴展方法:

public static class EnumerableExtensions 
{ 
    public static IEnumerable<SelectListItem> ToSelectList<T>(
     this IEnumerable<T> collection, 
     Func<T, object> textSelector, 
     Func<T, object> valueSelector) 
    { 
     // null checking omitted for brevity 
     foreach (var item in collection) 
     { 
      yield return new SelectListItem() 
      { 
       Text = textSelector(item) as string, 
       Value = valueSelector(item) as string 
      }; 
     } 
    } 
} 

你可以使用它在剃刀像這樣:

@Html.DropDownListFor(m => m.SelectedCity, Model.Cities.ToSelectList(c => c.CityName, city => c.CityId)) 
+0

儘管我同意@miguelerm的答案是可靠的,但我完全按照您在這裏描述的方式思考。 –

+0

爲什麼'object'而不是'string'?爲什麼'foreach' +'yield'而不是LINQ? –

+0

@Dan我選擇了'object'來避免在調用之前將值明確地轉換爲字符串。如果您在Razor中更加明確,您可以切換籤名以使用'string'值。我看到沒有必要使用LINQ進行投影,代碼非常簡單。 –

0

一致地命名您的模型將是最簡單的方法。假設你有分開的實體,如{ Id , Name},並使用該下拉式轉換的通用模型。 公共類下拉 {

public IEnumerable<int> SelectedItems 
    { 
     get; 
     set; 
    } 


    public IEnumerable<SelectListItem> Items 
    { 
     get; 
     set; 
    } 


    public IEnumerable<string> SelectedItemsString 
    { 
     get; 
     set; 
    } 
} 

無論你要多少列表項轉換成下拉列表傳遞給使用下拉實體,執行轉換並返回什麼ü期望輔助方法!

IEnumerable<SelectListItem> dropdownItems = new MultiSelectList(YourEntity, "ID", "Name", selectedId); 
      DropDown fboDropDown = new DropDown { Items = dropdownItems, SelectedItems = selectedId }; 

可用於下拉式以及多選擇列表

0

創建一個基類SelectListItem

public class SelectListItem 
{ 
    public virtual string Text { get; set; } 
    public virtual string Value { get; set; } 
} 

public class City : SelectListItem 
{ 
    public int CityId { get; set; } 
    public string CityName { get; set; } 
    public override string Text 
    { 
     get { return CityName; } 
     set { CityName = value; } 
    } 
    public override string Value 
    { 
     get { return CityId.ToString(); } 
     set { CityId = (int)value; } 
    } 
} 
public class State : SelectListItem 
{ 
    public int StateId { get; set; } 
    public string StateName { get; set; } 
    public string StateAbbreviation { get; set; } 
    public override string Text 
    { 
     get { return StateName; } 
     set { StateName = value; } 
    } 
    public override string Value 
    { 
     get { return StateId.ToString(); } 
     set { StateId = (int)value; } 
    } 
} 
1

這個怎麼樣:

var cities = new SelectList(cityList, "CityId", "CityName"); 
var states = new SelectList(cityList, "StateId", "StateAbbreviation"); 

的SelectList是casteable到IEnumerable<SelectListItem>

1

您所寫的任何通用方法都不會比僅使用Linq簡單得多Select

var cityList = cities.Select(c => new SelectListItem 
{ 
    Name = c.CityName, 
    Value = c.CityId.ToString() 
}); 

但是,如果你真的想使通用的,你可以這樣做:

public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> input, 
    Func<T, string> valueFunc, 
    Func<T, string> nameFunc) 
{ 
    return input.Select(i => new SelectListItem 
    { 
     Value = valueFunc(i), 
     Name = nameFunc(i) 
    }); 
} 

而且使用這樣的:

var cityList = cities.ToSelectList(c => c.CityId.ToString(), c => c.CityName); 
相關問題