页面数据输入的是一个List<TModel>的时。
用foreach(var item in Models)的时候
其中有Item 类里有Type属性,他们是枚举或是关联其它表的数据
此时要用DropDownList显示出来出来
如 Type: 1-小说;2-散文;3-诗;4-词;
var typeItem = new List<SelectListItem>(){
new SelectListItem(){ Value = "1",Text = "小说" },
new SelectListItem(){ Value = "2",Text = "散文" },
new SelectListItem(){ Value = "3",Text = "诗" },
new SelectListItem(){ Value = "4",Text = "词" },
};
cshtml界面
<table>
<tr>
<th>
序号
</th>
<th>
类型
</th>
</tr>
foreach(var item in Mode)
{
<tr>
<td>
item.id
</td>
<td>
@Html.DropDownListFor(item=>item.Type,typeItem);
</td>
<td>
....
</td>
</td>
}
</table>
老是显示第一个,明明将Type传入进去了,可还是不行。
如图所示
后来下载了MVC代码看了一下,原来在获取值的时候没有区分当前Type是
Lambda来至 List<TMode> 还是TModel
如果是TModel的话,传入Type是可以正确显示的
而在用List<TMode>的时候,就不行了
页面会将整个List<TModel>传入到后台去
这样他不知道当前如何去取当前是哪个TModel里Type里的值
于是我就增加了一个扩展,将当前的值,同时传入到后台去
这样就可以很好的显示出来了
将
@Html.DropDownListFor(item=>item.Type,typeItem);
改为
@Html.DropDownListFor(item=>item.Type,item.Type,typeItem);
下面把我写的扩展代码贴出来
个人水平有限
如果有什么不对地方,还望指整
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace Photography.CoreUI
{
/// <summary>
/// 下拉框扩展
/// mailto:xiaotuni@gmail.com
/// 我的BLOG http://blog.csdn.net/xiaotuni
/// </summary>
public static class XiaotuniDropDownListExtensions
{
static string MvcResources_HtmlHelper_MissingSelectData = "Missing Select Data";
static string MvcResources_HtmlHelper_WrongSelectDataType = "Wrong Select Data Type";
static string MvcResources_Common_NullOrEmpty = "Null Or Empty";
/// <summary>
/// 创建一个DropDownList控件
/// </summary>
/// <typeparam name="TModel">当前数据</typeparam>
/// <typeparam name="TProperty">属性</typeparam>
/// <param name="htmlHelper"></param>
/// <param name="expression">lambda 表达式</param>
/// <param name="defaultValue">默认值</param>
/// <param name="selectList">DropDownList里的数据</param>
/// <returns></returns>
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression, object defaultValue, IEnumerable<SelectListItem> selectList)
{
return DropDownListFor(htmlHelper, expression, defaultValue, selectList, null, null);
}
/// <summary>
/// 创建一个DropDownList控件
/// </summary>
/// <typeparam name="TModel">当前数据</typeparam>
/// <typeparam name="TProperty">属性</typeparam>
/// <param name="htmlHelper"></param>
/// <param name="expression">lambda 表达式</param>
/// <param name="defaultValue">默认值</param>
/// <param name="selectList">DropDownList里的数据</param>
/// <param name="optionLabel">标签名称</param>
/// <param name="htmlAttributes">DorpDownList属性</param>
/// <returns></returns>
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object defaultValue, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes)
{
if (expression == null)
{
throw new ArgumentNullException("expression");
}
string name = ExpressionHelper.GetExpressionText(expression);
return SelectInternal(htmlHelper, optionLabel, name, selectList, defaultValue, false, htmlAttributes);
}
/// <summary>
/// 获取选中项数据
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="name"></param>
/// <returns></returns>
static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name)
{
object o = null;
if (htmlHelper.ViewData != null)
{
o = htmlHelper.ViewData.Eval(name);
}
if (o == null)
{
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources_HtmlHelper_MissingSelectData,
name,
"IEnumerable<SelectListItem>"));
}
IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
if (selectList == null)
{
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources_HtmlHelper_WrongSelectDataType,
name,
o.GetType().FullName,
"IEnumerable<SelectListItem>"));
}
return selectList;
}
static object GetModelStateValue(HtmlHelper htmlHelper, string key, Type destinationType)
{
ModelState modelState;
if (htmlHelper.ViewContext.ViewData.ModelState.TryGetValue(key, out modelState))
{
if (modelState.Value != null)
{
return modelState.Value.ConvertTo(destinationType, null /* culture */);
}
}
return null;
}
static string ListItemToOption(SelectListItem item)
{
TagBuilder builder = new TagBuilder("option")
{
InnerHtml = HttpUtility.HtmlEncode(item.Text)
};
if (item.Value != null)
{
builder.Attributes["value"] = item.Value;
}
if (item.Selected)
{
builder.Attributes["selected"] = "selected";
}
return builder.ToString(TagRenderMode.Normal);
}
/// <summary>
///
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="optionLabel"></param>
/// <param name="name"></param>
/// <param name="selectList"></param>
/// <param name="selectedValue"></param>
/// <param name="allowMultiple"></param>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable<SelectListItem> selectList, object selectedValue, bool allowMultiple, IDictionary<string, object> htmlAttributes)
{
string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (String.IsNullOrEmpty(fullName))
{
throw new ArgumentException(MvcResources_Common_NullOrEmpty, "name");
}
bool usedViewData = false;
if (selectList == null)
{
selectList = htmlHelper.GetSelectData(fullName);
usedViewData = true;
}
object defaultValue = selectedValue != null ? selectedValue : (allowMultiple) ? GetModelStateValue(htmlHelper, fullName, typeof(string[])) : GetModelStateValue(htmlHelper, fullName, typeof(string));
if (!usedViewData)
{
if (defaultValue == null)
{
defaultValue = htmlHelper.ViewData.Eval(fullName);
}
}
if (defaultValue != null)
{
IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue };
IEnumerable<string> values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
List<SelectListItem> newSelectList = new List<SelectListItem>();
foreach (SelectListItem item in selectList)
{
item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
newSelectList.Add(item);
}
selectList = newSelectList;
}
StringBuilder listItemBuilder = new StringBuilder();
if (optionLabel != null)
{
listItemBuilder.AppendLine(ListItemToOption(new SelectListItem() { Text = optionLabel, Value = String.Empty, Selected = false }));
}
foreach (SelectListItem item in selectList)
{
listItemBuilder.AppendLine(ListItemToOption(item));
}
TagBuilder tagBuilder = new TagBuilder("select")
{
InnerHtml = listItemBuilder.ToString()
};
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("name", fullName, true /* replaceExisting */);
tagBuilder.GenerateId(fullName);
if (allowMultiple)
{
tagBuilder.MergeAttribute("multiple", "multiple");
}
ModelState modelState;
if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState))
{
if (modelState.Errors.Count > 0)
{
tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
}
}
tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));
return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
}
}
}