การเติมรายการแบบเลื่อนลงมีดโกนจากรายการ <วัตถุ> ใน MVC


124

ฉันมีโมเดล:

public class DbUserRole
    {
        public int UserRoleId { get; set; }
        public string UserRole { get; set; }
    }

public class DbUserRoles
    {
        public List<DbUserRole> GetRoles()
        {
            BugnetReports RoleDropDown = new BugnetReports();
            List<DbUserRole> Roles = new List<DbUserRole>();
            DataSet table = RoleDropDown.userRoleDropDown();
            foreach (DataRow item in table.Tables[0].Rows)
            {
                DbUserRole ur = new DbUserRole();
                ur.UserRole = Convert.ToString(item["UserRoleName"]);
                ur.UserRoleId = Convert.ToInt32(item["UserRoleID"]);
                Roles.Add(ur);
            }
            return Roles;
        }
    }

และนี่คือคอนโทรลเลอร์ที่โหลดมุมมอง:

        //
        // GET: /Admin/AddNewUser

        public ActionResult AddNewUser()
        {
            DbUserRoles Roles = new DbUserRoles();
            return View(Roles.GetRoles());
        }

ฉันสามารถรับรายการในรายการเพื่อแสดงโดยใช้การ@foreachวนซ้ำดังที่แสดงด้านล่าง:

@foreach (var item in Model)
       {
           <tr>
               <td>
                   @item.UserRoleId
               </td>
               <td>
                   @item.UserRole
               </td>
           </tr>
       }

แต่ฉันจะเติมข้อมูลในรายการแบบเลื่อนลงด้วยโมเดลที่ส่งผ่านได้อย่างไรฉันได้ลองแล้ว

@Html.DropDownListFor(x => x.UserRole)

แต่ฉันไม่มีโชค

คำตอบ:


242

คุณสามารถแยกตรรกะทางธุรกิจของคุณออกเป็นโมเดลมุมมองเพื่อให้มุมมองของคุณแยกออกจากกันได้ชัดเจนยิ่งขึ้น

ขั้นแรกให้สร้าง viewmodel เพื่อจัดเก็บ Id ที่ผู้ใช้จะเลือกพร้อมกับรายการของรายการที่จะปรากฏในไฟล์DropDown.

ViewModel:

public class UserRoleViewModel
{
    // Display Attribute will appear in the Html.LabelFor
    [Display(Name = "User Role")]
    public int SelectedUserRoleId { get; set; }
    public IEnumerable<SelectListItem> UserRoles { get; set; }
}

อ้างอิง:

ภายในตัวควบคุมสร้างวิธีการรับUserRoleรายการของคุณและแปลงเป็นรูปแบบที่จะนำเสนอในมุมมอง

ควบคุม:

private IEnumerable<SelectListItem> GetRoles()
{
    var dbUserRoles = new DbUserRoles();
    var roles = dbUserRoles
                .GetRoles()
                .Select(x =>
                        new SelectListItem
                            {
                                Value = x.UserRoleId.ToString(),
                                Text = x.UserRole
                            });

    return new SelectList(roles, "Value", "Text");
}

public ActionResult AddNewUser()
{
    var model = new UserRoleViewModel
                    {
                        UserRoles = GetRoles()
                    };
    return View(model);
}

อ้างอิง:

เมื่อสร้างวิวโมเดลแล้วตรรกะการนำเสนอก็ง่ายขึ้น

ดู:

@model UserRoleViewModel

@Html.LabelFor(m => m.SelectedUserRoleId)
@Html.DropDownListFor(m => m.SelectedUserRoleId, Model.UserRoles)

อ้างอิง:

สิ่งนี้จะผลิต:

<label for="SelectedUserRoleId">User Role</label>
<select id="SelectedUserRoleId" name="SelectedUserRoleId">
    <option value="1">First Role</option>
    <option value="2">Second Role</option>
    <option value="3">Etc...</option>
</select>

4
ฉันดีใจที่คุณพบว่ามีประโยชน์!
Dustin Kingen

สมมติว่านี่คือรายการที่มีตัวกรอง (ตารางที่แสดงผลลัพธ์ที่กรองโดยสิ่งที่อยู่ในเมนูแบบเลื่อนลง) คุณจะเพิ่มผลลัพธ์ของกริดในมุมมองเดียวกันนี้หรือไม่ ขอบคุณ
Ernesto

2
ขอบคุณนี่เป็นคำอธิบายที่ดีครั้งแรกที่ฉันพบเกี่ยวกับส่วนขยายมีดโกนนี้และรวมถึงการอ่านเอกสาร MS อย่างเป็นทางการ
Robert Christ

2
ยอดเยี่ยมและเป็นประโยชน์มาก สิ่งนี้จะถูกคั่นไว้สำหรับอนาคต! +1
Mike Upjohn

ในคอนโทรลเลอร์ของคุณคุณจะทำอย่างไรvar roles = dbUserRoles.GetRoles() ...เมื่อGetRolesเมธอดอยู่ในคอนโทรลเลอร์ในขณะที่dbUserRolesเป็นอินสแตนซ์ของคลาสโมเดล
Dylan Czenski

29
  @Html.DropDownList("ddl",Model.Select(item => new SelectListItem
{
    Value = item.RecordID.ToString(),
    Text = item.Name.ToString(),
     Selected = "select" == item.RecordID.ToString()
}))

5
ไม่ "? true: false" ซ้ำซ้อน?
Nathan Hartley

My Model ไม่มี Select คุณจะรู้ว่าทำไม?
A_Arnold

2
using System.Linq;เพื่อรับวิธีเลือกส่วนขยาย
ekolis

26

วิธีหนึ่งอาจเป็น;

    <select name="listbox" id="listbox">
    @foreach (var item in Model)
           {

                   <option value="@item.UserRoleId">
                      @item.UserRole 
                   </option>                  
           }
    </select>

2
คำตอบที่ดีฉันต้องการควบคุม html ที่ฉันผลิตอย่างเต็มที่
Alexander G

1
ยอดเยี่ยม สิ่งนี้จะต้องเป็นคำตอบที่ดีที่สุด ควบคุม HTML จริงๆ ขอบคุณ :)
Antonio

10

สิ่งที่ใกล้เคียงกับ:

@Html.DropDownListFor(m => m.UserRole, 
   new SelectList(Model.Roles, "UserRoleId", "UserRole", Model.Roles.First().UserRoleId), 
   new { /* any html  attributes here */ }) 

คุณต้องมี SelectList เพื่อเติมข้อมูล DropDownListFor สำหรับแอตทริบิวต์ HTML ที่คุณต้องการคุณสามารถเพิ่ม:

new { @class = "DropDown", @id = "dropdownUserRole" }

7

แทนที่จะเป็นList<UserRole>คุณสามารถปล่อยให้ Model ของคุณมีไฟล์SelectList<UserRole>. เพิ่มคุณสมบัติSelectedUserRoleIdเพื่อจัดเก็บ ... อืม ... ค่า Id ของ UserRole ที่เลือก

กรอก SelectList จากนั้นใน View ของคุณให้ใช้:

@Html.DropDownListFor(x => x.SelectedUserRoleId, x.UserRole)

และคุณควรจะสบายดี

ดูเพิ่มเติมhttp://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist(v=vs.108).aspx


2

คำเรียกร้องของคุณDropDownListForต้องการพารามิเตอร์เพิ่มเติมอีกสองสามประการเพื่อทำให้มันสมบูรณ์ คุณต้องมี SelectList ดังในคำถาม SO ต่อไปนี้:

MVC3 DropDownListFor - ตัวอย่างง่ายๆ?

ด้วยสิ่งที่คุณมีคุณบอกเพียงว่าเก็บข้อมูลไว้ที่ใดไม่ใช่ที่ที่จะโหลดรายการจากที่ใด


1
   @{
        List<CategoryModel> CategoryList = CategoryModel.GetCategoryList(UserID);
        IEnumerable<SelectListItem> CategorySelectList = CategoryList.Select(x => new SelectListItem() { Text = x.CategoryName.Trim(), Value = x.CategoryID.Trim() });
    }
    <tr>
        <td>
            <B>Assigned Category:</B>
        </td>
        <td>
            @Html.DropDownList("CategoryList", CategorySelectList, "Select a Category (Optional)")
        </td>
    </tr>

มีหลายคำตอบที่นี่ แต่คำตอบสุดท้ายควรแก้ปัญหา IMO ได้ดีที่สุด
Deathstalker

0

ฉันจะเข้าใกล้สิ่งนี้ราวกับว่าคุณมีโมเดลผู้ใช้:

Users.cs

public class Users
{
    [Key]
    public int UserId { get; set; }

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

    public int RoleId { get; set; }

    [ForeignKey("RoleId")]
    public virtual DbUserRoles DbUserRoles { get; set; }
}

และโมเดล DbUserRoles ที่แสดงตารางตามชื่อนั้นในฐานข้อมูล:

DbUserRoles.cs

public partial class DbUserRoles
{
    [Key]
    public int UserRoleId { get; set; }

    [Required]
    [StringLength(30)]
    public string UserRole { get; set; }
}

เมื่อคุณทำความสะอาดเรียบร้อยแล้วคุณควรจะสามารถสร้างและเติมเต็มคอลเล็กชัน UserRoles เช่นนี้ในคอนโทรลเลอร์ของคุณ:

var userRoleList = GetUserRolesList();
ViewData["userRoles"] = userRolesList;

และมีฟังก์ชั่นสนับสนุนเหล่านี้:

private static SelectListItem[] _UserRolesList;

/// <summary>
/// Returns a static category list that is cached
/// </summary>
/// <returns></returns>
public SelectListItem[] GetUserRolesList()
{
    if (_UserRolesList == null)
    {
        var userRoles = repository.GetAllUserRoles().Select(a => new SelectListItem()
         {
             Text = a.UserRole,
             Value = a.UserRoleId.ToString()
         }).ToList();
         userRoles.Insert(0, new SelectListItem() { Value = "0", Text = "-- Please select your user role --" });

        _UserRolesList = userRoles.ToArray();
    }

    // Have to create new instances via projection
    // to avoid ModelBinding updates to affect this
    // globally
    return _UserRolesList
        .Select(d => new SelectListItem()
    {
         Value = d.Value,
         Text = d.Text
    })
     .ToArray();
}

Repository.cs

ฟังก์ชัน My Repository GetAllUserRoles()สำหรับฟังก์ชันด้านบน:

public class Repository
{
    Model1 db = new Model1(); // Entity Framework context

    // User Roles
    public IList<DbUserRoles> GetAllUserRoles()
    {
        return db.DbUserRoles.OrderBy(e => e.UserRoleId).ToList();
    }
}

AddNewUser.cshtml

จากนั้นทำสิ่งนี้ในมุมมองของคุณ:

<table>
    <tr>
        <td>
            @Html.EditorFor(model => model.UserName,
                  htmlAttributes: new { @class = "form-control" }
                  )
        </td>
        <td>
            @Html.DropDownListFor(model => model.RoleId,
                  new SelectList( (IEnumerable<SelectListItem>)ViewData["userRoles"], "Value", "Text", model.RoleId),
                  htmlAttributes: new { @class = "form-control" }
                  )
         </td>
     </tr>
 </table>

-1
@model AdventureWork.CRUD.WebApp4.Models.EmployeeViewModel
@{
    ViewBag.Title = "Detalle";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Ingresar Usuario</h2>

@using (Html.BeginForm())
{

    @Html.AntiForgeryToken()
<div class="form-horizontal">


    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.PersonType, labelText: "Tipo de Persona", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.Employee.PersonType, new List<SelectListItem>
       {
               new SelectListItem{ Text= "SC", Value = "SC" },
               new SelectListItem{ Text= "VC", Value = "VC" },
                  new SelectListItem{ Text= "IN", Value = "IN" },
               new SelectListItem{ Text= "EM", Value = "EM" },
                new SelectListItem{ Text= "SP", Value = "SP" },

       }, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Employee.PersonType, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.EmployeeGender, labelText: "Genero", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.Employee.EmployeeGender, new List<SelectListItem>
       {
           new SelectListItem{ Text= "Masculino", Value = "M" },
           new SelectListItem{ Text= "Femenino", Value = "F" }
       }, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Employee.EmployeeGender, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.PersonTitle, labelText: "Titulo", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.PersonTitle, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.PersonTitle, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.PersonFirstName, labelText: "Primer Nombre", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.PersonFirstName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.PersonFirstName, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.PersonMiddleName, labelText: "Segundo Nombre", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.PersonMiddleName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.PersonMiddleName, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.PersonLastName, labelText: "Apellido", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.PersonLastName, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.PersonLastName, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.PersonSuffix, labelText: "Sufijo", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.PersonSuffix, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.PersonSuffix, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.DepartmentID, labelText: "Departamento", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.Employee.DepartmentID, new SelectList(Model.ListDepartment, "DepartmentID", "DepartmentName"), htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Employee.DepartmentID, "", new { @class = "text-danger" })
        </div>
    </div>


    <div class="form-group">
        @Html.LabelFor(model => model.Employee.EmployeeMaritalStatus, labelText: "Estado Civil", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.Employee.EmployeeMaritalStatus, new List<SelectListItem>
       {
           new SelectListItem{ Text= "Soltero", Value = "S" },
           new SelectListItem{ Text= "Casado", Value = "M" }
       }, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Employee.EmployeeMaritalStatus, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.ShiftId, labelText: "Turno", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.Employee.ShiftId, new SelectList(Model.ListShift, "ShiftId", "ShiftName"), htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Employee.ShiftId, "", new { @class = "text-danger" })
        </div>
    </div>



    <div class="form-group">
        @Html.LabelFor(model => model.Employee.EmployeeLoginId, labelText: "Login", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.EmployeeLoginId, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.EmployeeLoginId, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.EmployeeNationalIDNumber, labelText: "Identificacion Nacional", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.EmployeeNationalIDNumber, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.EmployeeNationalIDNumber, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.EmployeeJobTitle, labelText: "Cargo", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.EmployeeJobTitle, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.EmployeeJobTitle, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.EmployeeBirthDate, labelText: "Fecha Nacimiento", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.EmployeeBirthDate, new { htmlAttributes = new { @class = "form-control datepicker" } })
            @Html.ValidationMessageFor(model => model.Employee.EmployeeBirthDate, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.EmployeeSalariedFlag, labelText: "Asalariado", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.EmployeeSalariedFlag, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.EmployeeSalariedFlag, "", new { @class = "text-danger" })
        </div>
    </div>



    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Guardar" class="btn btn-default" />
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10" style="color:green">
            @ViewBag.Message
        </div>
        <div class="col-md-offset-2 col-md-10" style="color:red">
            @ViewBag.ErrorMessage
        </div>
    </div>
</div>


}

คุณช่วยอธิบายคำตอบของคุณได้ไหม? ซึ่งจะช่วยให้เข้าใจโซลูชันของคุณได้ง่ายขึ้น
CodeF0x

จะไม่เป็นประโยชน์มากนักหากคุณไม่อธิบายคำตอบและรหัสของคุณ โปรดพิจารณาเพิ่มคำชี้แจง
f-CJ

เขาแทรกรายการด้วยตนเอง แต่สิ่งนี้จะไม่เป็นประโยชน์มากนักหากคุณมีหลายร้อยหรือหลายพันรายการ ควรรวมEmployeeViewModelและEmployeeแม้ว่าเพื่อแสดงวัตถุที่นั่นและประเภทของพวกเขา
vapcguy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.