Asp.net mvc 创建一个类似于DropDownListFor的ASP.NET MVC Html帮助程序

Asp.net mvc 创建一个类似于DropDownListFor的ASP.NET MVC Html帮助程序,asp.net-mvc,html-helper,mvc-editor-templates,Asp.net Mvc,Html Helper,Mvc Editor Templates,在某些情况下,我希望不使用DropDownListForhelper显示SelectList对象。相反,我想创建一个在SelectListItems上迭代的助手,并绘制一些不同的东西 我已经创建了一个EditorTemplate: @model RadioButtonOptions <div class=" switch-field noselect" style="padding-left: 0px;"> @foreach (SelectListItem op in Mo

在某些情况下,我希望不使用
DropDownListFor
helper显示
SelectList
对象。相反,我想创建一个在SelectListItems上迭代的助手,并绘制一些不同的东西

我已经创建了一个EditorTemplate:

@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>
public class RadioButtonOptions
    {
        public SelectList Values { get; set; }
    }
public class MainVisitVM
{
    public MainVisit Visit { get; set; }

    public RadioButtonOptions VisitOptions { get; set; }
}
    <div class="clearfix">
        @Html.LabelFor(x=> x.Visit.Tipo)
        <div class="input">
            @Html.EditorFor(x=> x.VisitOptions ) //HERE
        </div>
    </div>
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());
        } 
最终结果如下所示:

@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>
public class RadioButtonOptions
    {
        public SelectList Values { get; set; }
    }
public class MainVisitVM
{
    public MainVisit Visit { get; set; }

    public RadioButtonOptions VisitOptions { get; set; }
}
    <div class="clearfix">
        @Html.LabelFor(x=> x.Visit.Tipo)
        <div class="input">
            @Html.EditorFor(x=> x.VisitOptions ) //HERE
        </div>
    </div>
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());
        } 

我的视图模型如下(简化):

@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>
public class RadioButtonOptions
    {
        public SelectList Values { get; set; }
    }
public class MainVisitVM
{
    public MainVisit Visit { get; set; }

    public RadioButtonOptions VisitOptions { get; set; }
}
    <div class="clearfix">
        @Html.LabelFor(x=> x.Visit.Tipo)
        <div class="input">
            @Html.EditorFor(x=> x.VisitOptions ) //HERE
        </div>
    </div>
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());
        } 
我在Razor视图中使用它作为:

@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>
public class RadioButtonOptions
    {
        public SelectList Values { get; set; }
    }
public class MainVisitVM
{
    public MainVisit Visit { get; set; }

    public RadioButtonOptions VisitOptions { get; set; }
}
    <div class="clearfix">
        @Html.LabelFor(x=> x.Visit.Tipo)
        <div class="input">
            @Html.EditorFor(x=> x.VisitOptions ) //HERE
        </div>
    </div>
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());
        } 

@LabelFor(x=>x.Visit.Tipo)
@Html.EditorFor(x=>x.VisitOptions)//此处
我的问题是,我希望它更像DropDownListFor,因此我传递的lamda expresion是保存选定值的属性,然后只传递SelectList对象(或自定义列表)


@LabelFor(x=>x.Visit.Tipo)
@Html.CustomDropDownListFor(x=>x.Visit.Tipo,Model.VisitOptions)//这将是理想的!!
因此,我认为使用EditorTemplates进行此操作是不可能的。
有没有办法做到这一点?

多亏了@
StephenMuecke
的建议,我最终得到了这个
HtmlHelper
扩展方法:

@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>
public class RadioButtonOptions
    {
        public SelectList Values { get; set; }
    }
public class MainVisitVM
{
    public MainVisit Visit { get; set; }

    public RadioButtonOptions VisitOptions { get; set; }
}
    <div class="clearfix">
        @Html.LabelFor(x=> x.Visit.Tipo)
        <div class="input">
            @Html.EditorFor(x=> x.VisitOptions ) //HERE
        </div>
    </div>
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());
        } 
public static MvcHtmlString radiobuttonnforselectlist(
这个HtmlHelper HtmlHelper,
表情表情,
选择列表(值列表)
{
字符串htmlFieldName=ExpressionHelper.GetExpressionText(表达式);
if(listOfValues==null)返回MvcHtmlString.Create(string.Empty);
var wrapperDiv=新标记生成器(“div”);
wrapperDiv.AddCssClass(“开关字段选择”);
Add(“style”,“padding left:0px;”);
var sb=新的StringBuilder();
foreach(在listOfValues中选择ListItem项)
{
var idLabelF=htmlFieldName.Replace(“.”,“”)+““+项.Value;
var label=htmlHelper.label(idLabelF,item.Text,new{style=“width:100px;”}).ToHtmlString();
var radio=htmlhelp.RadioButtonFor(表达式,item.Value,new{id=idLabelF}).ToHtmlString();
sb.附件格式(“{0}{1}”,收音机,标签);
}
wrapperDiv.InnerHtml=sb.ToString();
返回MvcHtmlString.Create(wrapperDiv.ToString());
} 

我对我的
htmlFieldName.Replace(“.”,“”)
)并不特别自豪,但它是有效的。

这是可能的-通过将列表作为
additionalViewData
传递,并使用(比如)
var list=ViewData[…”]在模板中获取它
,但是使用
HtmlHelper
扩展方法会更好。@StephenMuecke我将尝试HtmlHelper扩展方法。。。谢谢请注意,
HtmlHelper
已经包含一个静态方法
GenerateIdFromName(字符串名称)
,但是您也可以将html作为
yourText
生成,并使用
var radio=HtmlHelper.RadioButtonFor(表达式,item.Value,new{id=”“})
要删除
id
,除非您特别需要为css或javascript selectorYeap删除id,radiobutton的id必须与标签中的for属性匹配,才能具有预期的行为。可能正在更改您所指的标记,但最终结果相同。谢谢