【问题标题】:ASP.NET MVC DropDownListFor with Nested Properties in ModelASP.NET MVC DropDownListFor 与模型中的嵌套属性
【发布时间】:2011-02-26 16:52:37
【问题描述】:

我有两个类,一个是 Entry 和 Paradigm。 Entry 类有一个 ParadigmId 和一个 Paradigm 属性。所以在我看来我有@Model.Entry.Paradigm。如何使用 Paradigm 模型的新语法构建 DropDownListFor?

   // Entry Model
    [Bind(Exclude = "EntryId")]
    public class Entry
    {
        [ScaffoldColumn(false)] 
        public int EntryId { get; set; }
 .
        [Display(Name = "Type")]
        public int ParadigmId { get; set; }

        public virtual Paradigm Paradigm { get; set; }
    }

// Paradigm Model
public class Paradigm
{
    [ScaffoldColumn(false)]
    public int ParadigmId { get; set; }

    [Required]
    public string Name { get; set; }

    public List<Entry> Entries { get; set; } 
}

在我看来,我有@Html.DropDownListFor(model =&gt; model.Entry.ParadigmId, model.Entry.Paradigm)。但是该模型的类型是 Paradigm 而不是 IEnumerable。由于 Paradigm 是我的课程的一部分(对于 Entity Framework Code First),我不需要使用大多数示例中列出的单独的 ViewData/ViewBag。

我在 Google 上搜索了一下,发现有人使用 Helper/Extension 方法将模型转换为 SelectList。在我的模型中使用 DropDownListFor 的最佳方式是什么?

    @* Create View *@
    <div class="editor-label">
        @Html.LabelFor(model => model.Entry.ParadigmId)
    </div>
    <div class="editor-field">   
        @Html.DropDownListFor(model => model.Entry.ParadigmId, model.Entry.Paradigm)
        @Html.ValidationMessageFor(model => model.Entry.ParadigmId)
    </div>

【问题讨论】:

    标签: asp.net-mvc entity-framework-4 razor


    【解决方案1】:

    您的链接 Entry.Paradigm 延迟加载一个范式,即外键引用的范式。它不会加载数据库中的所有范式。

    如果你想要一个包含所有范式的下拉列表,绑定到选定的范式。然后,您将需要一个单独的 ViewBag 或 Model 属性,其中包含所有这些属性的列表。

    【讨论】:

      【解决方案2】:

      我一直在使用:

      public abstract class DropdownVm
      {
          /// <summary>
          /// Set up a dropdown with the indicated values
          /// </summary>
          /// <param name="value">the current value, for determining selection</param>
          /// <param name="options">list of options to display</param>
          /// <param name="prependLabelAndValues">list of alternating label/value entries to insert to the beginning of the list</param>
          public List<SelectListItem> SetDropdown<T>(T value, IEnumerable<KeyValuePair<T, string>> options, params object[] prependLabelAndValues)
          {
              var dropdown = options.Select(o => new SelectListItem { Selected = Equals(o.Key, value), Value = o.Key.ToString(), Text = o.Value }).ToList();
      
              // insert prepend objects
              for (int i = 0; i < prependLabelAndValues.Length; i += 2)
              {
                  dropdown.Insert(0, new SelectListItem { Text = prependLabelAndValues[i].ToString(), Value = prependLabelAndValues[i + 1].ToString() });
              }
      
              return dropdown;
          }
      }
      
      /// <summary>
      /// ViewModel with a single dropdown representing a "single" value
      /// </summary>
      /// <typeparam name="T">the represented value type</typeparam>
      public class DropdownVm<T> : DropdownVm
      {
          /// <summary>
          /// Flag to set when this instance is a nested property, so you can determine in the view if `!ModelState.IsValid()`
          /// </summary>
          public virtual bool HasModelErrors { get; set; }
      
          /// <summary>
          /// The user input
          /// </summary>
          public virtual T Input { get; set; }
      
          /// <summary>
          /// Dropdown values to select <see cref="Input"/>
          /// </summary>
          public virtual List<SelectListItem> Dropdown { get; set; }
      
          /// <summary>
          /// Set up <see cref="Dropdown"/> with the indicated values
          /// </summary>
          /// <param name="availableOptions">list of options to display</param>
          /// <param name="prependLabelAndValues">list of alternating label/value entries to insert to the beginning of the list</param>
          public virtual void SetDropdown(IEnumerable<KeyValuePair<T, string>> availableOptions, params object[] prependLabelAndValues)
          {
              this.Dropdown = SetDropdown(this.Input, availableOptions, prependLabelAndValues);
          }
      
          public override string ToString()
          {
              return Equals(Input, default(T)) ? string.Empty : Input.ToString();
          }
      }
      

      您创建的对象:

      var vm = new DropdownVm<string>();
      vm.SetDropdown(new Dictionary<string, string> {
          { "option1", "Label 1" },
          { "option2", "Label 2" },
      }, "(Choose a Value)", string.Empty);
      

      或者,更具体地说,在您的情况下:

      var models = yourDataProvider.GetParadigms(); // list of Paradigm
      var vm = new DropdownVm<int>();
      vm.SetDropdown(
          models.ToDictionary(m => m.ParadigmId, m => m.Name),
           "(Choose a Value)", string.Empty
      );
      

      并在视图中渲染:

      <div class="field">
          @Html.LabelFor(m => m.Input, "Choose")
          @Html.DropDownListFor(m => m.Input, Model.Dropdown)
          @Html.ValidationMessageFor(m => m.Input)
      </div>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-07
        • 2011-01-28
        • 2023-03-12
        • 1970-01-01
        • 2014-08-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多