ASP.NET MVC内置支持DropDownList编辑器模板

Sib*_*Guy 8 asp.net-mvc

有没有办法说我的视图模型属性应该呈现为DropDownList(以便我可以指定DropDownList项目)?

我发现了很多自定义实现,但我想应该有一种内置的方法来实现这样一个基本的东西.

更新.我通过Html.EditorForModel方法渲染我的模型,我不想使用像这样的方法Html.DropDownListFor

Dar*_*rov 14

有这使得一个下拉列表中,除了没有内置的模板,Nullable<bool>这使得一个类型Not Set,Yes,No下拉但我认为这不是你问什么.

所以让我们建立一个.与往常一样,我们首先定义视图模型,该模型将表示包含2个属性的下拉列表(一个用于选定值,另一个用于可用值):

public class ItemViewModel
{
    public string SelectedId { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以使用这个属性的标准视图模型:

public class MyViewModel
{
    public ItemViewModel Item { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后是一个将填充视图模型的控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Item = new ItemViewModel
            {
                SelectedId = "2",
                Items = new[]
                {
                    new SelectListItem { Value = "1", Text = "item 1" },
                    new SelectListItem { Value = "2", Text = "item 2" },
                    new SelectListItem { Value = "3", Text = "item 3" },
                }
            }
        };
        return View(model);
    }
}
Run Code Online (Sandbox Code Playgroud)

和相应的视图(~/Views/Home/Index.cshtml):

@model MyViewModel
@using (Html.BeginForm())
{
    @Html.EditorForModel()
}
Run Code Online (Sandbox Code Playgroud)

现在剩下的就是为DropDownViewModeltype(~/Views/Shared/EditorTemplates/DropDownViewModel.cshtml)定义一个自定义编辑器模板:

@model DropDownViewModel
@Html.DropDownListFor(
    x => x.SelectedId, 
    new SelectList(Model.Items, "Value", "Text", Model.SelectedId)
)
Run Code Online (Sandbox Code Playgroud)

并覆盖Object类型的默认模板,以便允许Deep Dive,如Brad Wilson所述his blog post.否则,默认情况下,ASP.NET MVC不会递归到模板的复杂子类型.所以我们覆盖~/Views/Shared/EditorTemplates/Object.cshtml:

@foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit && !ViewData.TemplateInfo.Visited(pm))) 
{
    if (prop.HideSurroundingHtml) 
    {
        @Html.Editor(prop.PropertyName)
    } 
    else 
    { 
        <div class="editor-label">
            @(prop.IsRequired ? "*" : "")
            @Html.Label(prop.PropertyName)
        </div>
        <div class="editor-field">
            @Html.Editor(prop.PropertyName)
            @Html.ValidationMessage(prop.PropertyName, "*")
        </div>
    }
}
Run Code Online (Sandbox Code Playgroud)