web-dev-qa-db-fra.com

Remplir une liste déroulante de rasoirs à partir d'un <objet> List dans MVC

J'ai un modèle:

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

Et voici le contrôleur qui charge la vue:

        //
        // GET: /Admin/AddNewUser

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

Je peux obtenir les éléments de la liste à afficher en utilisant une boucle @foreach comme indiqué ci-dessous:

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

Mais comment puis-je remplir une liste déroulante avec le modèle qui est traversé, j'ai essayé

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

mais je n'ai pas de chance.

114
Win

Vous pouvez séparer votre logique métier en un modèle de vue, de sorte que votre vue présente une séparation plus nette.

Créez d'abord un modèle de vue pour stocker l'identifiant que l'utilisateur sélectionnera, ainsi qu'une liste d'éléments qui apparaîtront dans la variable 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; }
}

Références:

Dans le contrôleur, créez une méthode pour obtenir votre liste UserRole et la transformer en formulaire qui sera présenté dans la vue.

Manette:

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

Références:

Maintenant que le modèle de vue est créé, la logique de présentation est simplifiée

Vue:

@model UserRoleViewModel

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

Références:

Cela produira:

<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>
228
Romoku
  @Html.DropDownList("ddl",Model.Select(item => new SelectListItem
{
    Value = item.RecordID.ToString(),
    Text = item.Name.ToString(),
     Selected = "select" == item.RecordID.ToString()
}))
27
Ankita Singh

Une façon pourrait être;

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

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

Quelque chose près de:

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

Vous avez besoin d'une liste de sélection pour renseigner DropDownListFor. Pour tous les attributs HTML dont vous avez besoin, vous pouvez ajouter:

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

Au lieu d'un List<UserRole>, vous pouvez laisser votre modèle contenir un SelectList<UserRole>. Ajoutez également une propriété SelectedUserRoleId à stocker ... eh bien ... la valeur Id de l’utilisateur définie.

Remplissez la liste de sélection, puis dans votre vue, utilisez:

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

et ça devrait aller.

Voir aussi http://msdn.Microsoft.com/en-us/library/system.web.mvc.selectlist(v=vs.108).aspx .

7
Roy Dictus

Votre appel à DropDownListFor a besoin de quelques paramètres supplémentaires pour l'étoffer. Vous avez besoin d'une liste de sélection comme dans la question SO suivante:

MVC3 DropDownListFor - un exemple simple?

Avec ce que vous avez là, vous lui avez seulement indiqué où stocker les données, pas où charger la liste.

2
MisterJames
   @{
        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>
1
Deathstalker

Je vais aborder ceci comme si vous aviez un modèle Utilisateurs:

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

et un modèle DbUserRoles représentant une table portant ce nom dans la base de données:

DbUserRoles.cs

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

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

Une fois ces opérations nettoyées, vous devriez pouvoir créer et remplir une collection de rôles d’utilisateur, comme celle-ci, dans votre contrôleur:

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

et ont ces fonctions de support:

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

Ma fonction de référentiel GetAllUserRoles() pour la fonction ci-dessus:

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

Ensuite, faites ceci dans votre vue:

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