【问题标题】:Create an ASP.NET MVC Html helper similar to DropDownListFor创建一个类似于 DropDownListFor 的 ASP.NET MVC Html 帮助器
【发布时间】:2017-09-28 10:09:29
【问题描述】:

在某些情况下,我想显示 SelectList 对象而不使用 DropDownListFor 助手。相反,我想创建一个迭代 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>

RadioButtonOptions 类是一个 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 是不可能的。 任何想法如何做到这一点?

【问题讨论】:

  • 这是可能的 - 通过将列表传递为additionalViewData 并使用(比如)var List = ViewData["...."]; 在模板中获取它,但HtmlHelper 扩展方法会更好。
  • @StephenMuecke 我会尝试 HtmlHelper 扩展方法...谢谢!

标签: asp.net-mvc html-helper mvc-editor-templates


【解决方案1】:

感谢@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(".","_") 感到骄傲,但很有效。

【讨论】:

  • 请注意 HtmlHelper 已经包含一个静态方法 GenerateIdFromName(string name) 但您也可以将 html 生成为 &lt;label&gt;&lt;input type="radio" ...... /&gt;&lt;span&gt;yourText&lt;/span&gt;&lt;/label&gt; 并使用 var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = "" }) 删除 id 除非您特别需要css 或 javascript 选择器
  • 是的,单选按钮的 id 必须与标签中的 FOR 属性匹配,才能获得预期的行为。可能正在更改您指出的标记具有相同的最终结果。谢谢!
猜你喜欢
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 2011-04-06
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多