创建一个类似于 DropDownListFor 的 ASP.NET MVC Html 助手
Create an ASP.NET MVC Html helper similar to DropDownListFor
在某些情况下,我想显示 SelectList
不使用 DropDownListFor
助手的对象。相反,我想创建一个遍历 SelectListItems 的助手,并绘制一些不同的东西。
我创建了一个编辑器模板:
@model RadioButtonOptions
<div class=" switch-field noselect" style="padding-left: 0px;">
@foreach (SelectListItem op in Model.Values.Items)
{
var idLabelF = ViewData.TemplateInfo.GetFullHtmlFieldId("") + "_" + op.Value;
var esChecked = "";
if (op.Selected)
{
esChecked = "checked";
}
<input type="radio" id="@idLabelF" name="@(ViewData.TemplateInfo.GetFullHtmlFieldName(""))" value="@op.Value" @esChecked />
<label for="@idLabelF" style="width: 100px;">@op.Text</label>
}
</div>
RadioButtonOptions
class是一个ViewModel:
public class RadioButtonOptions
{
public SelectList Values { get; set; }
}
最终结果如下所示:
我的ViewModel是这样的(简化):
public class MainVisitVM
{
public MainVisit Visit { get; set; }
public RadioButtonOptions VisitOptions { get; set; }
}
我在 Razor View 中使用它作为:
<div class="clearfix">
@Html.LabelFor(x=> x.Visit.Tipo)
<div class="input">
@Html.EditorFor(x=> x.VisitOptions ) //HERE
</div>
</div>
我遇到的问题是我希望它更像 DropDownListFor,所以我传递的 lamda 表达式是 属性 保存所选值,然后只传递 SelectList 对象(或自定义列表)。
<div class="clearfix">
@Html.LabelFor(x=> x.Visit.Tipo)
<div class="input">
@Html.CustomDropDownListFor(x=> x.Visit.Tipo, Model.VisitOptions ) //This would be ideal!!
</div>
</div>
所以,我认为使用 EditorTemplates 做这件事是不可能的。
知道如何实现这个吗?
感谢@StephenMuecke
的建议,我最终得到了这个HtmlHelper
扩展方法:
public static MvcHtmlString RadioButtonForSelectList<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
SelectList listOfValues)
{
string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
if (listOfValues == null) return MvcHtmlString.Create(string.Empty);
var wrapperDiv = new TagBuilder("div");
wrapperDiv.AddCssClass("switch-field noselect");
wrapperDiv.Attributes.Add("style", "padding-left: 0px;");
var sb = new StringBuilder();
foreach (SelectListItem item in listOfValues)
{
var idLabelF = htmlFieldName.Replace(".","_") + "_" + item.Value;
var label = htmlHelper.Label(idLabelF, item.Text, new { style = "width: 100px;" }).ToHtmlString();
var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = idLabelF }).ToHtmlString();
sb.AppendFormat("{0}{1}", radio, label);
}
wrapperDiv.InnerHtml = sb.ToString();
return MvcHtmlString.Create(wrapperDiv.ToString());
}
对我的 htmlFieldName.Replace(".","_")
并不感到特别自豪,但确实有效。
在某些情况下,我想显示 SelectList
不使用 DropDownListFor
助手的对象。相反,我想创建一个遍历 SelectListItems 的助手,并绘制一些不同的东西。
我创建了一个编辑器模板:
@model RadioButtonOptions
<div class=" switch-field noselect" style="padding-left: 0px;">
@foreach (SelectListItem op in Model.Values.Items)
{
var idLabelF = ViewData.TemplateInfo.GetFullHtmlFieldId("") + "_" + op.Value;
var esChecked = "";
if (op.Selected)
{
esChecked = "checked";
}
<input type="radio" id="@idLabelF" name="@(ViewData.TemplateInfo.GetFullHtmlFieldName(""))" value="@op.Value" @esChecked />
<label for="@idLabelF" style="width: 100px;">@op.Text</label>
}
</div>
RadioButtonOptions
class是一个ViewModel:
public class RadioButtonOptions
{
public SelectList Values { get; set; }
}
最终结果如下所示:
我的ViewModel是这样的(简化):
public class MainVisitVM
{
public MainVisit Visit { get; set; }
public RadioButtonOptions VisitOptions { get; set; }
}
我在 Razor View 中使用它作为:
<div class="clearfix">
@Html.LabelFor(x=> x.Visit.Tipo)
<div class="input">
@Html.EditorFor(x=> x.VisitOptions ) //HERE
</div>
</div>
我遇到的问题是我希望它更像 DropDownListFor,所以我传递的 lamda 表达式是 属性 保存所选值,然后只传递 SelectList 对象(或自定义列表)。
<div class="clearfix">
@Html.LabelFor(x=> x.Visit.Tipo)
<div class="input">
@Html.CustomDropDownListFor(x=> x.Visit.Tipo, Model.VisitOptions ) //This would be ideal!!
</div>
</div>
所以,我认为使用 EditorTemplates 做这件事是不可能的。 知道如何实现这个吗?
感谢@StephenMuecke
的建议,我最终得到了这个HtmlHelper
扩展方法:
public static MvcHtmlString RadioButtonForSelectList<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
SelectList listOfValues)
{
string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
if (listOfValues == null) return MvcHtmlString.Create(string.Empty);
var wrapperDiv = new TagBuilder("div");
wrapperDiv.AddCssClass("switch-field noselect");
wrapperDiv.Attributes.Add("style", "padding-left: 0px;");
var sb = new StringBuilder();
foreach (SelectListItem item in listOfValues)
{
var idLabelF = htmlFieldName.Replace(".","_") + "_" + item.Value;
var label = htmlHelper.Label(idLabelF, item.Text, new { style = "width: 100px;" }).ToHtmlString();
var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = idLabelF }).ToHtmlString();
sb.AppendFormat("{0}{1}", radio, label);
}
wrapperDiv.InnerHtml = sb.ToString();
return MvcHtmlString.Create(wrapperDiv.ToString());
}
对我的 htmlFieldName.Replace(".","_")
并不感到特别自豪,但确实有效。