Tạo danh sách thả xuống dao cạo từ Danh sách <object> trong MVC


124

Tôi có một mô hình:

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

Và đây là Trình điều khiển tải chế độ xem:

        //
        // GET: /Admin/AddNewUser

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

Tôi có thể nhận các mục trong danh sách để hiển thị bằng @foreachvòng lặp như hình dưới đây:

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

Nhưng làm thế nào để tôi đưa vào danh sách thả xuống với mô hình được truyền qua, tôi đã thử

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

nhưng tôi không gặp may

Câu trả lời:


242

Bạn có thể tách logic kinh doanh của mình thành một khung nhìn, để khung nhìn của bạn có sự phân tách rõ ràng hơn.

Trước tiên, hãy tạo một chế độ xem để lưu trữ Id mà người dùng sẽ chọn cùng với danh sách các mục sẽ xuất hiện trong 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; }
}

Người giới thiệu:

Bên trong bộ điều khiển tạo một phương thức để lấy UserRoledanh sách của bạn và biến nó thành dạng sẽ được trình bày trong dạng xem.

Điều khiển:

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

Người giới thiệu:

Bây giờ, viewmodel được tạo, logic trình bày được đơn giản hóa

Lượt xem:

@model UserRoleViewModel

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

Người giới thiệu:

Điều này sẽ tạo ra:

<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
Tôi rất vui vì bạn thấy nó hữu ích!
Dustin Kingen

Giả sử đây là danh sách có các bộ lọc (lưới hiển thị kết quả được lọc theo nội dung thả xuống). Bạn có thể thêm các kết quả lưới vào cùng một chế độ xem không? Cảm ơn
Ernesto

2
Cảm ơn bạn, đây là lời giải thích tốt đầu tiên tôi tìm thấy về phần mở rộng dao cạo này và bao gồm cả việc đọc tài liệu MS chính thức.
Robert Christ

2
Tuyệt vời và rất hữu ích. Điều này sẽ được đánh dấu cho tương lai! +1
Mike Upjohn

Trong bộ điều khiển của bạn, bạn làm thế nào var roles = dbUserRoles.GetRoles() ...khi GetRolesphương thức được đặt trong bộ điều khiển, trong khi đó dbUserRoleslà một thể hiện của lớp mô hình?
Dylan Cundredki

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

5
Không phải là "? Đúng: sai" dư thừa?
Nathan Hartley

Mô hình của tôi không có Chọn. Bạn có biết tại sao không?
A_Arnold

2
using System.Linq;để có được phương thức Chọn mở rộng.
ekolis

26

Một cách có thể là;

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

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

2
Câu trả lời hay, tôi muốn có toàn quyền kiểm soát html mà tôi sản xuất
Alexander G

1
Thông minh! Đây phải là câu trả lời tốt nhất. Thực sự kiểm soát HTML. Cảm ơn :)
Antonio

10

Một cái gì đó gần với:

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

Bạn cần có một ListList để điền vào DropDownListFor. Đối với bất kỳ thuộc tính HTML nào bạn cần, bạn có thể thêm:

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

7

Thay vì a List<UserRole>, bạn có thể để Mô hình của mình chứa a SelectList<UserRole>. Đồng thời thêm thuộc tính SelectedUserRoleIdđể lưu trữ ... à ... giá trị Id của UserRole đã chọn.

Điền vào danh sách Chọn, sau đó trong Chế độ xem của bạn sử dụng:

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

và bạn sẽ ổn thôi

Xem thêm http://msdn.microsoft.com/en-us/l Library / system.web.mvc.selectlist (v = vs.108) .aspx .


2

Cuộc gọi của bạn DropDownListForcần thêm một vài thông số để xác thực. Bạn cần một danh sách chọn như trong câu hỏi SO sau:

MVC3 DropDownListFor - một ví dụ đơn giản?

Với những gì bạn có ở đó, bạn chỉ cho nó biết nơi lưu trữ dữ liệu, không phải nơi tải danh sách từ đó.


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>

Một số câu trả lời ở đây nhưng câu trả lời cuối cùng này sẽ giải quyết vấn đề IMO tốt nhất.
Deathstalker

0

Tôi sẽ tiếp cận điều này như thể bạn có một mô hình Người dùng:

Người dùng.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; }
}

và một mô hình DbUserRoles đại diện cho một bảng theo tên đó trong cơ sở dữ liệu:

DbUserRoles.cs

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

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

Khi bạn đã dọn sạch, bạn sẽ có thể tạo và điền vào bộ sưu tập UserRoles, như thế này, trong Trình điều khiển của bạn:

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

và có các chức năng hỗ trợ này:

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

Kho lưu trữ.cs

Chức năng Kho lưu trữ của tôi GetAllUserRoles()cho chức năng, ở trên:

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

Sau đó, làm điều này trong Chế độ xem của bạn:

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


}

Bạn có thể giải thích câu trả lời của bạn, xin vui lòng? Điều đó sẽ làm cho nó dễ dàng hơn để hiểu giải pháp của bạn.
CodeF0x

Sẽ không hữu ích lắm nếu bạn không giải thích câu trả lời và mã của mình. Vui lòng xem xét thêm một số làm rõ
f-CJ

Anh ta tự tay chèn các mục. Nhưng điều này không hữu ích nếu bạn có hàng trăm hoặc hàng ngàn mục. Nên bao gồm EmployeeViewModelEmployee, mặc dù, để hiển thị các đối tượng ở đó và các loại của chúng.
vapcguy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.