我从数据库填充Dropdownlist,我想通过设置“class”属性来显示某些红色元素。所以,我尝试了很多方法,后来我为Dropdownlist创建了一个自定义HTML Helper。但它没有任何意义,虽然它似乎是添加了类属性,但这个参数不能从Controller传递给Razor View。你能帮忙吗?
MyHelper.cs:
public static MvcHtmlString Custom_DropdownList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> list, object htmlAttributes)
{
TagBuilder dropdown = new TagBuilder("select");
dropdown.Attributes.Add("name", name);
dropdown.Attributes.Add("id", name);
StringBuilder options = new StringBuilder();
foreach (var item in list)
{
options = options.Append("<option value='" + item.Value + "'>" + item.Text + "</option>");
}
dropdown.InnerHtml = options.ToString();
dropdown.MergeAttributes(new RouteValueDictionary(htmlAttributes));
return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}
的控制器:
private void PopulateMeetingsDropDownList(object selectedMeetings = null)
{
var meetingsQuery = repository.Meetings
.Join(repository.Cities, m => m.MeetingCityId, c => c.CityID,
(m, c) => new
{
CityID = c.CityID,
CityName = c.CityName,
MeetingDate = m.MeetingStartDate
}
)
.OrderBy(x => x.CityID)
.AsEnumerable()
.Select(
i => new
{
CityID = i.CityID,
Name = string.Format(
"{0} ({1:dd MMMM yyyy})",
i.CityName, i.MeetingDate),
Expired = i.MeetingDate < DateTime.UtcNow
}
).ToList();
var selectItems = new List<SelectListItem>(meetingsQuery.Count);
foreach (var record in meetingsQuery)
{
var item = new SelectListItem
{
Text = record.Name,
Value = record.Name
};
if (record.Expired)
{
item.Attributes.Add("class", "disabled"); //!!! Problem on this line
}
selectItems.Add(item);
}
ViewData["MeetingId"] = new SelectList(meetingsQuery, "CityID", "Name", selectedMeetings);
}
但在应用此方法后,我收到错误“'System.Web.Mvc.SelectListItem'不包含'Attributes'的定义,也没有扩展方法'Attributes'接受类型的第一个参数...”。因此,我认为我需要使用另一个属性或帮助程序将类属性分配给自定义racords(在“if(record.Expired)”行上过滤记录没有问题。)
查看:
@Html.Custom_DropdownList("MeetingId", ViewData["MeetingId"] as SelectList, new { id = "meetingId"})
你能澄清一下如何提供这个吗?提前谢谢。
以下是具有Class和Disabled属性能力的修改代码:
更新的代码(适用于MyDropdownListFor):
自定义HTML帮助程序类:
public static class MyHelpers
{
public class MySelectItem : SelectListItem
{
public string Class { get; set; }
public string Disabled { get; set; }
}
public static MvcHtmlString MyDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<MySelectItem> list, string optionLabel, object htmlAttributes)
{
return MyDropdownList(htmlHelper, ExpressionHelper.GetExpressionText(expression), list, optionLabel, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString MyDropdownList(this HtmlHelper htmlHelper, string name, IEnumerable<MySelectItem> list, string optionLabel, IDictionary<string, object> htmlAttributes)
{
TagBuilder dropdown = new TagBuilder("select");
dropdown.Attributes.Add("name", name);
dropdown.Attributes.Add("id", name);
StringBuilder options = new StringBuilder();
// Make optionLabel the first item that gets rendered.
if (optionLabel != null)
options = options.Append("<option value='" + String.Empty + "'>" + optionLabel + "</option>");
foreach (var item in list)
{
if(item.Disabled == "disabled")
options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "' disabled='" + item.Disabled + "'>" + item.Text + "</option>");
else
options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "'>" + item.Text + "</option>");
}
dropdown.InnerHtml = options.ToString();
dropdown.MergeAttributes(new RouteValueDictionary(htmlAttributes));
return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}
}
控制器:
private void PopulateMeetingsDropDownList(object selectedMeetings = null)
{
var meetingsQuery = repository.Meetings
.Join(repository.Cities, m => m.MeetingCityId, c => c.CityID,
(m, c) => new
{
CityID = c.CityID,
CityName = c.CityName,
MeetingDate = m.MeetingStartDate
}
)
.OrderBy(x => x.CityID)
.AsEnumerable()
.Select(
i => new
{
Value = i.CityID.ToString(),
DisplayValue = string.Format(
"{0} ({1:dd MMMM yyyy})",
i.CityName, i.MeetingDate),
Expired = i.MeetingDate < DateTime.UtcNow
}
).ToList();
var selectItems = new List<MyHelpers.MySelectItem>(meetingsQuery.Count);
foreach (var record in meetingsQuery)
{
var item = new MyHelpers.MySelectItem
{
Text = record.DisplayValue,
Value = record.Value
};
if (record.Expired)
{
item.Class = "disabled";
item.Disabled = "disabled";
}
selectItems.Add(item);
}
ViewBag.MeetingData = selectItems;
}
查看:
<label>Meeting</label>
@Html.MyDropdownListFor(m => m.MeetingId, ViewBag.MeetingData as List<MyHelpers.MySelectItem>, "---- Select ----",
new { name = "meetingId", id = "meetingId"})
答案 0 :(得分:2)
TL; DR; 您正在使用SelectList
,但您不需要。
创建一个新视图模型类,您将传递给视图。它将包含您需要的所有属性,可能如下所示:
自定义类,用于保存有关项目的信息:
public class CustomSelectItem
{
public string Text {get;set;}
public string Value {get;set;}
public string Class {get;set;}
public bool Selected {get;set;}
}
由于您使用ViewData传递此数据,因此您没有任何限制,可以在那里放置任何内容。我建议您使用ViewBag而不是ViewData。
在您的控制器中,您可以创建一个新的List<CustomSelectItem>
并传递它。构建集合时,如果项目已过期,只需将Class属性设置为“disabled”或您正在使用的任何内容。这是代码(我跳过你开会的部分):
<强>控制器:强>
var selectItems = new List<CustomSelectItem>(meetingsQuery.Count);
foreach (var record in meetingsQuery)
{
var item = new CustomSelectItem
{
Text = record.Name,
Value = record.Name
};
if (record.Expired)
{
item.Class = "disabled";
}
selectItems.Add(item);
}
ViewBag.MeetingData = selectItems;
然后修改您创建的自定义帮助程序方法,以接受CustomSelectItem
而不是SelectListItem
的集合。您可以直接编写HTML,因为您可以访问Class属性。
自定义助手方法:
public static MvcHtmlString Custom_DropdownList(this HtmlHelper helper, string name, IList<CustomSelectItem> list, object htmlAttributes)
{
TagBuilder dropdown = new TagBuilder("select");
dropdown.Attributes.Add("name", name);
dropdown.Attributes.Add("id", name);
StringBuilder options = new StringBuilder();
foreach (var item in list)
{
options = options.Append("<option value='" + item.Value + "' class='" + item.Class + "'>" + item.Text + "</option>");
}
dropdown.InnerHtml = options.ToString();
dropdown.MergeAttributes(new RouteValueDictionary(htmlAttributes));
return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}
完成此操作后,您可以从视图中调用帮助程序,如下所示:
查看:强>
@Html.Custom_DropdownList("MeetingId", ViewBag.MeetingData as List<CustomListItem>, new { id = "meetingId"})
答案 1 :(得分:2)
您可以继承SelectList并将自己的属性添加到类中,如下所示:
public class MySelectListItem : SelectListItem
{
public bool Highlighted { get; set; }
}
拥有自定义类后,您可以根据它编写助手。您可以应用不同的css类或更改样式属性。
public static class MyHtmlHelpers
{
public static MvcHtmlString DropDownListHighlighted(this HtmlHelper helper, string name, IEnumerable<MySelectListItem> itens)
{
StringBuilder dropDown = new St();
dropDown.AppendFormat("<select id='{0}' name='{0}'>", name);
foreach (var item in itens)
{
dropDown.AppendFormat("<option selected='{2}' value='{1}' class='{3}'>{0}</option>",
item.Text,
item.Value,
item.Selected ? "selected" : "",
item.Highlighted ? "highlighted" : "normal");
}
dropDown.Append("</select>");
return MvcHtmlString.Create(dropDown.ToString());
}
}
在您的视图中(不要忘记在web.config或视图中添加HTML帮助程序类的命名空间):
@Html.DropDownListHighlighted("DropDown", ViewData["DropDownOptions"] as List<MySelectListItem>)
DropDownListHighlightedFor
你可以做类似的事情来实现一个简单的DropDownListHighlightedFor:
public static MvcHtmlString DropDownListHighlightedFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<MySelectListItem> itens)
{
return DropDownListHighlighted(htmlHelper, ExpressionHelper.GetExpressionText(expression), itens);
}
在视图中:
@Html.DropDownListHighlightedFor(x => x.Option, ViewData["DropDownOptions"] as List<MySelectListItem>)