嗨,所以我對MVC3和Razor相當陌生,在過去的幾天裏我一直試圖讓自己的頭靠近它。我的項目架構師已經給我一個任務來創建一個幫助器方法,該方法對MVC視圖中的下拉列表進行排序。我有一個View從Controller中檢索各種數據,並返回一些我想要顯示在下拉列表中的值。我被告知不要在Controller中對它進行排序,並且還要將我們想要排序的字段傳遞給輔助方法。我能做到這一點像之下,但建築師希望保持觀點自由的升C代碼:使用幫助器方法在MVC3/Razor中對DropDownList進行排序的最佳方法
@Html.DropDownListFor(model => model.StudyName, new SelectList(ViewBag.StudyTypes, "Value", "Text").OrderBy(l => l.Text))
所以我創造了一些示例代碼和一些擴展方法,試圖得到它的工作。我的想法是複製現有的Html.DropDownList方法並允許傳遞'object htmlAttributes',這樣我可以將該樣式設置爲方法調用的一部分。
這是我的代碼到目前爲止。我倒返回數據爲下降ViewBag.StudyTypes在編輯器的方法:
public ActionResult Edit(int id)
{
IEnumerable<SelectListItem> mySelectList = new List<SelectListItem>();
IList<SelectListItem> myList = new List<SelectListItem>();
for (int i = 0; i < 5; i++)
{
myList.Add(new SelectListItem()
{ Value = i.ToString(), Text = "My Item " + i.ToString(), Selected = i == 2 }
);
}
mySelectList = myList;
ViewBag.StudyTypes = mySelectList;
StudyDefinition studydefinition = db.StudyDefinitions.Find(id);
return View(studydefinition);
}
這裏是我查看代碼:
@model MyStudyWeb.Models.StudyDefinition
@using MyStudyWeb.Helpers
@{
ViewBag.Mode = "Edit";
}
<div>
@Html.DropDownListSorted(new SelectList(ViewBag.StudyTypes, "Value", "Text"))<br />
@Html.DropDownListSorted("MyList", new SelectList(ViewBag.StudyTypes, "Value", "Text"))<br />
</div>
最後下面是擴展方法我想上班。第一種擴展方法什麼都不做,我只是在視圖中的那一點上得到一個空格。第二種方法的作品,但它很醜。對於第三種方法,我不知道如何指定'order by'參數,因爲IEnumerable上的OrderBy需要Linq表達式。
namespace StudyDefinition.Helpers
{
public static class HtmlHelperExtensions
{
// 1st sort method: sort the passed in list and return a new sorted list
public static SelectList DropDownListSorted(this HtmlHelper helper, IEnumerable<SelectListItem> selectList)
{
var x = new SelectList(selectList.ToList()).OrderBy(l => l.Text);
return x as SelectList;
}
// 2nd sort method: return IHtml string and create <select> list manually
public static IHtmlString DropDownListSorted(this HtmlHelper helper, string name, SelectList selectList)
{
StringBuilder output = new StringBuilder();
(selectList).OrderBy(l => l.Text);
output.Append("<select id=" + name + " name=" + name + ">");
foreach (var item in selectList)
{
output.Append("<option value=" + item.Value.ToString() + ">" + item.Text + "</option>");
}
output.Append("</select>");
return MvcHtmlString.Create(output.ToString());
}
// 3rd sort method: pass in order by parameter - how do I use this?
public static IHtmlString DropDownListSorted(this HtmlHelper helper, string name, SelectList selectList, string orderBy)
{
StringBuilder output = new StringBuilder();
//How do I use the orderBy parameter?
(selectList).OrderBy(l => l.Text);
output.Append("<select id=" + name + " name=" + name + ">");
foreach (var item in selectList)
{
output.Append("<option value=" + item.Value.ToString() + ">" + item.Text + "</option>");
}
output.Append("</select>");
return MvcHtmlString.Create(output.ToString());
}
}
}
我真的不知道該採取最好的方法,有可能是我完全缺少一個更簡單的方法,我可能會點在哪裏,我不能見樹不見林了。一些問題
我應該返回一個SelectList還是一個MvcHtmlString,或者其他什麼東西?
對於第一個擴展方法,我該如何獲取返回的SelectList以在View中呈現?
如何將參數傳遞給指定排序順序的擴展方法?
如何傳遞'object htmlAttributes'參數,以及如何將此對象/參數應用於SelectList?
如果有人有一些想法或建議,那麼我會很感激一些反饋:)
嗨@Darin非常感謝。但是,我正在處理現有系統,並且所有視圖都有多個下拉列表,並且它們全都作爲ViewBag屬性從控制器返回。所以我不能改變這種做法。其次,View已經在做'返回View(studydefinition)'這是Entity類。有沒有另一種方法可以返回視圖模型?第三,當我添加你的擴展方法時,DropDownListFor方法不被識別,我得到:'System.Web.Mvc.HtmlHelper'不包含'DropDownListFor'的定義 –
@Ciaran Bruen,對於現有系統和ViewBag 。我只是提到它爲未來的代碼,以避免這種不好的做法。如果您有多個下拉列表,則只需在視圖模型上擁有多個「IEnumerable」屬性。關於'return View(studydefinition)',這是將視圖模型傳遞給視圖的正確方法。第三,在'System.Web.Mvc.Html'命名空間中定義了'DropDownListFor'擴展方法,因此只需在包含'DropDownListForSorted'幫助器的文件頂部的這個命名空間中添加一個using以使其進入作用域。 –