Mengisi daftar tarik-turun pisau cukur dari Daftar <objek> di MVC

124

Saya punya model:

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

Dan inilah Controller yang memuat view:

        //
        // GET: /Admin/AddNewUser

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

Saya bisa mendapatkan item dalam daftar untuk ditampilkan menggunakan @foreach loop seperti yang ditunjukkan di bawah ini:

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

Tetapi bagaimana cara mengisi daftar dropdown dengan model yang dilalui, saya telah mencoba

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

tapi aku tidak beruntung.

Menang
sumber

Jawaban:

242

Anda dapat memisahkan logika bisnis Anda menjadi model tampilan, sehingga tampilan Anda memiliki pemisahan yang lebih rapi.

Pertama buat model tampilan untuk menyimpan Id yang akan dipilih pengguna bersama dengan daftar item yang akan muncul di 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; }
}

Referensi:

Di dalam pengontrol, buat metode untuk mendapatkan UserRoledaftar Anda dan mengubahnya menjadi bentuk yang akan disajikan dalam tampilan.

Pengontrol:

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

Referensi:

Sekarang viewmodel dibuat, logika presentasi disederhanakan

Melihat:

@model UserRoleViewModel

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

Referensi:

Ini akan menghasilkan:

<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>
Dustin Kingen
sumber
4
Saya senang Anda merasa terbantu!
Dustin Kingen
Katakanlah ini adalah daftar dengan filter (kotak yang menunjukkan hasil yang difilter oleh whats di drop down). Apakah Anda akan menambahkan hasil grid ke tampilan yang sama ini? Terima kasih
Ernesto
2
Terima kasih, ini adalah penjelasan bagus pertama yang saya temukan tentang ekstensi pisau cukur ini, dan itu termasuk membaca dokumen resmi MS.
Robert Christ
2
Fantastis dan sangat membantu. Ini akan ditandai untuk masa depan! +1
Mike Upjohn
Di pengontrol Anda, bagaimana Anda melakukannya var roles = dbUserRoles.GetRoles() ...ketika GetRolesmetode terletak di pengontrol, sedangkan dbUserRolesinstance dari kelas model?
Dylan Czenski
29
  @Html.DropDownList("ddl",Model.Select(item => new SelectListItem
{
    Value = item.RecordID.ToString(),
    Text = item.Name.ToString(),
     Selected = "select" == item.RecordID.ToString()
}))
Ankita Singh
sumber
5
Bukankah "? True: false" berlebihan?
Nathan Hartley
Model Saya tidak memiliki Select. Tahukah kamu kenapa?
A_Arnold
2
using System.Linq;untuk mendapatkan metode Pilih ekstensi.
ekolis
26

Satu cara mungkin;

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

                   <option value="@item.UserRoleId">
                      @item.UserRole 
                   </option>                  
           }
    </select>
neildt
sumber
2
Jawaban yang bagus, saya ingin memiliki kendali penuh atas html yang saya hasilkan
Alexander G
1
Luar biasa! Ini harus menjadi jawaban terbaik. Benar-benar kendalikan HTML. Terima kasih :)
Antonio
10

Sesuatu yang dekat dengan:

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

Anda memerlukan SelectList untuk mengisi DropDownListFor. Untuk atribut HTML apa pun yang Anda butuhkan, Anda dapat menambahkan:

new { @class = "DropDown", @id = "dropdownUserRole" }
Jonesopolis
sumber
7

Alih-alih a List<UserRole>, Anda bisa membiarkan Model Anda berisi file SelectList<UserRole>. Juga tambahkan properti SelectedUserRoleIduntuk menyimpan ... yah ... nilai Id UserRole yang dipilih.

Isi SelectList, lalu gunakan View Anda:

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

dan kamu akan baik-baik saja.

Lihat juga http://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist(v=vs.108).aspx .

Roy Dictus
sumber
2

Panggilan Anda ke DropDownListFormembutuhkan beberapa parameter lagi untuk menyempurnakannya. Anda memerlukan SelectList seperti pada pertanyaan SO berikut:

MVC3 DropDownListFor - contoh sederhana?

Dengan apa yang Anda miliki di sana, Anda hanya memberi tahu di mana menyimpan data, bukan dari mana memuat daftar.

MisterJames
sumber
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>
Deathstalker
sumber
Beberapa jawaban di sini tetapi yang terakhir ini harus menyelesaikan masalah IMO terbaik.
Deathstalker
0

Saya akan mendekati ini seolah-olah Anda memiliki model Pengguna:

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

dan model DbUserRoles yang merepresentasikan tabel dengan nama tersebut di database:

DbUserRoles.cs

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

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

Setelah Anda membersihkannya, Anda hanya dapat membuat dan mengisi koleksi UserRoles, seperti ini, di Controller Anda:

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

dan memiliki fungsi pendukung ini:

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

Fungsi Repositori saya GetAllUserRoles()untuk fungsi di atas:

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

Kemudian lakukan ini di View Anda:

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


}
Hector Gutierrez
sumber
Bisakah Anda menjelaskan jawaban Anda? Itu akan membuatnya lebih mudah untuk memahami solusi Anda.
CodeF0x
Tidak terlalu membantu jika Anda tidak menjelaskan jawaban dan kode Anda. Harap pertimbangkan untuk menambahkan beberapa klarifikasi
f-CJ
Dia memasukkan item secara manual. Tetapi ini tidak terlalu membantu jika Anda memiliki ratusan atau ribuan entri. Seharusnya memasukkan EmployeeViewModeldan Employee, meskipun, untuk menunjukkan objek di sana, dan tipenya.
vapcguy