使用自定义编辑器模板时未选择下拉列表值

本文关键字:选择 下拉列表 自定义 编辑器 | 更新日期: 2023-09-27 18:28:31

我有一个简单的自定义编辑器模板,用于下拉列表,其中显示国家列表(国家名称、数字ID)。我通过ViewModel1将一个数字ID传递给View,这样就已经在下拉列表中选择了特定的国家/地区。并且国家id不会被选中,即使该模型包含CountryID。

使用选项3(参见模板代码),它确实预先选择了国家,但MVC更改了下拉列表的id和名称,例如,如果传递给编辑器模板的名称(属性名称)是"CountryID",MVC设置id="*CountryID_CountryID*"和name="CountryID.CountryID"。当然,当值在视图模型中发布时,绑定会混乱,因为属性名称只是CountryID。

问题:我需要在自定义编辑器模板代码中做什么,以便在国家/地区列表下拉列表中预先选择国家/地区?传递给视图的模型包含国家/地区的CountryID。

编辑器模板代码:

@model short
@using PSP.Lib;
@{
    SelectList TheSelectList = null;
    string FieldName = ViewData.ModelMetadata.PropertyName;  //FieldName only used when I tried the commented out option.
    TheSelectList = DLists.GetCountriesList();  //just gets list of countries and a numeric id for each.
}

        <div class="editor-label">
            @Html.LabelFor(model => model)
        </div>
        <div class="editor-field">
            @Html.DropDownList("", TheSelectList)  //==1. country id passed thru model does not get selected on list.
         @* @Html.DropDownListFor(model => model, TheSelectList)  *@   //==2. as above, does not work.
         @* @Html.DropDownList(FieldName, TheSelectList) *@  //==3. country id passed thru model DOES get selected BUT, id and name parameters get changed.
        </div>

视图:仅显示相关代码

@model PSP.ViewModels.ViewModel1
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>EventList</legend>
            @Html.EditorFor(model => model.CountryID)
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

VIEWMODEL1:仅显示相关代码

namespace PSP.ViewModels
{
    public class ViewModel1
    {
        public short CountryID { get; set; }
    }
}

国家列表:

public static SelectList GetCountriesList()
        {
            AccDBEntities db = new AccDBEntities();
            var ls = (from ct in db.Countries
                      select new { Text = ct.NameText, Value = ct.ID, Selected = false }).ToList();
            return new SelectList(ls, "Value", "Text");
        }

控制器:仅显示相关代码

        public ActionResult Create()
        {
            ViewModel1 VM1 = new ViewModel1();
            VM1.CountryID = 50;    //just pre-selecting a country id in the dropdown list
            return View(VM1);
        }

使用自定义编辑器模板时未选择下拉列表值

首先,您不应该创建一个静态方法来获取国家列表。将国家列表添加到您的ViewModel中,如下所示:

namespace PSP.ViewModels
{
    public class ViewModel1 // Choose a more meaningful name for your ViewModel
    {
        public short CountryID { get; set; }
        public IEnumerable<Country> CountriesList { get; set; }
    }
}

然后,在控制器操作中,您将获得:

public ActionResult Create()
{
    ViewModel1 VM1 = new ViewModel1();
    VM1.CountryID = 50;    //just pre-selecting a country id in the dropdown list
    using(AccDBEntities db = new AccDBEntities())
    {
        VM1.CountriesList = (from ct in db.Countries
                             select ct).ToList(); 
    }
    return View(VM1);
}

而且,在您看来,您将拥有(您不需要EditorTemplate):

@model PSP.ViewModels.ViewModel1
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>EventList</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.CountryID)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.CountryID, 
              new SelectList(Model.Countries, "ID", "NameText", Model.CountryID))  
        </div> 
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

更新:

如果你想使用EditorTemplate,你必须在ViewModel中使用UIHint属性,如下所示:

namespace PSP.ViewModels
{
    public class ViewModel1 // Choose a more meaningful name for your ViewModel
    {
        [UIHint("CountryID")]
        public short CountryID { get; set; }
        public IEnumerable<Country> CountriesList { get; set; }
    }
}

然后,创建一个PartialView,如下所示,将其命名为CountryID.cshtml,并将其放置在Views'Shared'EditorTemplates下。

@model short
<div class="editor-label">
    @Html.LabelFor(model => model)
</div>
<div class="editor-field">
    @Html.DropDownList("", 
      new SelectList(ViewBag.Countries, "ID", "NameText", Model)
</div>

并且,在您的主视图中,您将看到:

@model PSP.ViewModels.ViewModel1
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>EventList</legend>
        @Html.EditorFor(model => model.CountryID, Model.Countries)
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}