模型中具有嵌套属性的 ASP.NET MVC DropDownListFor

发布于 2024-10-19 06:24:26 字数 1378 浏览 1 评论 0原文

我有两个课程:入门课程和范式课程。 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 => model.Entry.ParadigmId, model.Entry.Paradigm)。但模型的类型是 Paradigm 而不是 IEnumerable。由于 Paradigm 是我的类的一部分(对于实体框架代码优先),我不需要使用大多数示例中列出的单独的 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>

I have two classes an Entry and Paradigm. The Entry class has a ParadigmId and a Paradigm property. So in my view I have @Model.Entry.Paradigm. How do I build a DropDownListFor using the newer syntax for the Paradigm model?

   // 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; } 
}

In my view I have @Html.DropDownListFor(model => model.Entry.ParadigmId, model.Entry.Paradigm). But the model is of type Paradigm not IEnumerable. Since Paradigm is part of my class (for Entity Framework Code First) I do not need to use a separate ViewData/ViewBag that is listed in most examples.

I Googled a bit and saw individuals using Helper/Extension methods to convert a model into a SelectList. What is the best way to use DropDownListFor in my model?

    @* 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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温馨耳语 2024-10-26 06:24:27

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

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

Your link Entry.Paradigm lazy loads a single Paradigm, the one referenced by the foreign key. It does not load all the Paradigm's in the database.

If you want to have a dropdown list of all the paradigms, bound to the selected one. Then you will need a separate ViewBag or Model property that contains a list of the them all.

巡山小妖精 2024-10-26 06:24:27

我一直在使用:

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>

I've been using:

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();
    }
}

Which you create with:

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

or, more specifically in your case:

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
);

And render in the view with:

<div class="field">
    @Html.LabelFor(m => m.Input, "Choose")
    @Html.DropDownListFor(m => m.Input, Model.Dropdown)
    @Html.ValidationMessageFor(m => m.Input)
</div>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文