【问题标题】:C# MVC DropDownListFor in a table of editable recordsC# MVC DropDownListFor 在可编辑记录表中
【发布时间】:2014-07-28 03:20:11
【问题描述】:

我不确定这是否可行,也没有发现任何类似的问题。

我们有一个编辑视图,它不是针对单个记录,而是针对“父”记录的多个成员。这些“子”记录需要一起(同时)编辑。 ...如果可能的话。

每个“子”记录中的一个字段是对另一个表的引用,因此需要选择列表。我们在所有标准编辑视图中都使用 DropDownListFor,并且单条记录编辑正常。

我们对这个问题的模型是:

    [Display(Name = "Team Member")]
    public int Contact_ID { get; set; }
    [Display(Name = "Team Member")]
    public String Contact_Name { get; set; }

    [Display(Name = "Type/Role")]
    public int MemberTypeLookUp_ID { get; set; }
    [Display(Name = "Type/Role")]
    public String MemberTypeValue { get; set; }
    [Display(Name = "Type/Role")]
    public LookUpList MemberTypeLookUp { get; set; }

我们通过从数据库表中选择来检索前 4 个字段。直截了当,OK..

我们设置 DropDownListFor 的代码是:

(编辑:在 foreach() 循环中添加的新代码以手动将每个列表中相关选项的 .Selected 属性设置为 true。这仍然不会转换为实际显示的视图...)

    foreach (TeamEditViewItem tevi in this.members)
    {
        tevi.MemberTypeLookUp = new LookUpList("TeamMemberType");

        foreach (SelectListItem item in tevi.MemberTypeLookUp.list)
        {
            if (item.Value == tevi.MemberTypeLookUp_ID.ToString())
            {
                item.Selected = true;
                break;
            }
        }
    }

为了完成这个问题,LookUpList 代码是:

public class LookUpList 
{
    public SelectList list;

    // Return all Active LookUp entries for the passed-in Category.
    public LookUpList(String Category)
    {
        WorkpointContext _db = new WorkpointContext();

        int Customer_ID = _db.GetCustomer_ID();

        IList<LookUp> items = (from lookup in _db.LookUp
                                where (lookup.Category == Category)
                                && (lookup.IsActive == true)
                                orderby lookup.DisplayOrder ascending
                                select lookup).ToList();

        this.list = new SelectList(items, "ID", "Value");
    }

}

如上所述,LookUpList 代码适用于标准编辑视图上的单个记录。

渲染页面后,我们会列出多个“子”记录,但是下拉列表不包含每个记录的现有值。 (这是 EDIT 而不是 Create,因此已经通过默认值和其他逻辑分配了值 - 而不是通过 Create View 上的 DropDown 列表。

查看页面源码时,我可以看到每个 DropDown Lists 都有自己的 ID。

我感觉我们的问题是由于页面上的多个 DropDownListFor 对象造成的,但无法弄清楚问题是什么以及为什么会出现问题。

我们的视图有 DropDownList 的简单代码:

    @Html.DropDownListFor(model => model.members[i].MemberTypeLookUp_ID, Model.members[i].MemberTypeLookUp.list, "--Select--")
    @Html.ValidationMessageFor(model => model.members[i].MemberTypeLookUp_ID)

添加第三个参数是因为我们总是在下拉列表中获得第一个选项,并且需要确定是否有值。 我们不断地在下拉列表中显示“--Select--”选项,这是一个占位符而不是有效选项 - 因此会显示验证消息。

(编辑)我已经添加了完整的编辑视图 cshtml 代码:

@model WebWorkPoint.Models.TeamEditView
<h3>Edit Team</h3>
@using (Html.BeginForm()) {
    <fieldset>
        @if (Model.members.Count>0)
        {
            <table>
            <!-- table headings -->
            <thead>
            <tr>
                <td style="text-align:center; border-bottom: 1px solid black; " >
                    <div class='editor-label'>
                        @Html.LabelFor(m => m.members.First().Contact_Name)
                    </div>
                </td>
                <td class="spacer-border"> </td>
                <td style="text-align:center; border-bottom: 1px solid black; " >
                    <div class='editor-label'>
                        @Html.LabelFor(m => m.members.First().MemberTypeValue)
                    </div>
                </td>
            </tr>
            </thead>

            <!-- table rows -->
            <tbody>
                @for (int i = 0; i < Model.members.Count; i++)
                {
                    <tr>
                        <td style="text-align:center; " >
                            @Html.HiddenFor(m => m.members[i].Contact_ID)
                            <div class="editor-field">
                                @Html.EditorFor(m => m.members[i].Contact_Name)
                                @Html.ValidationMessageFor(model => model.members[i].Contact_Name)
                            </div>
                        </td>
                        <td class="spacer"></td>
                        <td style="text-align:center; " >
                            <div class="editor-field">
                                @Html.DropDownListFor(model => model.members[i].MemberTypeLookUp_ID, Model.members[i].MemberTypeLookUp.list, "--Select--")
                                @Html.ValidationMessageFor(model => model.members[i].MemberTypeLookUp_ID)
                            </div>
                        </td>
                    </tr>
                }
            </table>
        }
        else
        {
            <p>There are currently no team members defined.</p>
        }
        <p>
            <input type="submit" value="Update Team" />
            @{
                sAction = "/" + Model.TableNameValue + "/" + Model.TableNameValue + "Show/" + Model.TableRecord_ID.ToString();
                sLinkText = "Cancel";
            }
            <button type="button" onclick="location.href='@sAction'" >@sLinkText</button>
        </p>
    </fieldset>
}

(结束编辑)

谁能解释一下我们的问题?提前感谢您的帮助。

【问题讨论】:

  • 无法发现您的视图代码有任何问题。您确定您有一个与MemberTypeLookUp_ID 的值匹配的option
  • 通读页面的“查看源代码”,与典型的编辑视图相比,id列表中的option 值之一。 IS 缺少的一件事是正常下拉列表中的selected="selected" 部分。在控制器中设置视图时,我会尝试在“手动”foreach() 循环期间手动设置相关选项。
  • 即使手动设置每个列表中相关项目的.Selected 属性也不会转换为视图本身。我已更新原始问题/问题中的 foreach() 代码以显示此新代码。我将在这里补充一点,在调试中单步执行代码会执行“预期”的所有操作。
  • 这甚至没有必要。我怀疑问题可能是您在属性名称MemberTypeLookUp_ID 中有一个下划线。尝试删除下划线,看看是否有效。
  • 不,恐怕没有运气。我想你可能已经成功了,因为我们的代码可能违反了一些奇怪的规则,但结果是一样的。我可以看到现在已删除下划线的查看源代码(即:id="members_0__MemberTypeLookUpID" name="members[0].MemberTypeLookUpID"),但所有下拉列表仍然没有选择任何值。令人费解...

标签: c# asp.net-mvc asp.net-mvc-3 model-view-controller html.dropdownlistfor


【解决方案1】:

阅读this answer on Stack Overflow后,我们决定尝试相同的分辨率。

事实证明,完整分辨率如下:

  1. 我们仍然需要在设置代码中设置 LookUpList(但不需要尝试任何选择代码):

    // other code above ...
    foreach (TeamEditViewItem tevi in this.members)
    {
        tevi.MemberTypeLookUp = new LookUpList("TeamMemberType");
    }
    
  2. LookUpList() 代码根据原始问题/问题创建 SelectList - 无需更改。

  3. 我们还需要替换编辑视图上的 DropDownListFor() 调用:

    @Html.DropDownListFor(model => model.members[i].MemberTypeLookUp_ID, new SelectList(Model.members[i].MemberTypeLookUp.list, "Value", "Text", Model.members[i].MemberTypeLookUp_ID), "--Select--")
    

这似乎是重复或多余的,但这是必需的。也许我们可以做一些事情来进一步清理它,但它现在“没有坏”,那么为什么要尝试修复它呢?

我必须感谢 @Stephen Muecke 和 @Mario Lopez 的投入,让我们能够从我们正在做的事情中进一步调查和思考。另外,感谢@ataravati 解决了上面链接的其他问题,让我们尝试其他方法。

希望我们的问题和解决方案可以帮助其他程序员......

【讨论】:

    【解决方案2】:

    我认为正在发生的事情是所有下拉菜单都是使用相同的 Id = MemberTypeLookUp_ID 生成的。我要做的是为孩子创建一个局部视图,并从 foreach 内的主视图调用它,然后只将必须填充的子模型而不是整个父模型传递给这个局部视图。

    【讨论】:

    • 每条记录的id和name字段是:id="members_0__MemberTypeLookUp_ID" name="members[0].MemberTypeLookUp_ID"id="members_1__MemberTypeLookUp_ID" name="members[1].MemberTypeLookUp_ID"id="members_2__MemberTypeLookUp_ID" name="members[2].MemberTypeLookUp_ID"他们有不同的idname值吗? ...似乎我不知道如何格式化 cmets ...
    • 我已经通过了这里的团队。我们不确定您的意思。 (我不得不承认,我们不是语言专家)
    • 您能粘贴您的视图吗?我认为你要做什么会更清楚。谢谢。
    • 我现在已经添加了完整的编辑视图 cshtml 代码。它位于原始问题/问题的末尾。希望这会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多