web-dev-qa-db-fra.com

MVC SelectList combinant plusieurs colonnes dans un champ de texte

Comment générer une liste de sélection, où le champ de texte est composé de deux colonnes de texte ou plus, par exemple: lorsque j'ai un champ Description et taux dans ma base de données, je veux les combiner pour afficher:

Large--£200
Medium--£150
Small--£100

Le code du contrôleur est:

 var stands = db.Stands.Where(s => s.ExhibitorID == null).ToList();
 ViewBag.StandID = new SelectList(stands,"StandID", "Description" + "-- £" + "Rate");

... et ma vue est (actuellement):

    <div class="editor-field"> 
        @Html.DropDownList("StandID", "--Select--") 
    </div> 

... mais la "Description" + "- £" + "Tarif"); ne fonctionnera pas:

DataBinding: 'System.Data.Entity.DynamicProxies.Stand_63F8C9F623B3C0E57D3008A57081AFCD9C39E1A6B79B0380B60840F1EFAE9DB4' ne contient pas de propriété portant le nom 'Description-- £ Rate'.

Merci pour toute aide,

Marque

47
Mark

Vous pouvez créer une nouvelle classe anonyme à l'aide d'une simple projection LINQ, puis utiliser la fonction SelectList(IEnumerable, string, string)surcharge du constructeur pour spécifier la valeur et les champs de texte à utiliser pour la fonction <option> éléments à savoir:

var stands = 
  db.Stands
    .Where(s => s.ExhibitorID == null)
    .Select(s => new 
     { 
       StandID = s.StandID,
       Description = string.Format("{0}-- £{1}", s.Description, s.Rate) 
     })
    .ToList();

ViewBag.StandID = new SelectList(stands, "StandID", "Description")

Modifier

En C # 6 et versions ultérieures, interpolation de chaîne permet une meilleure lecture que string.Format

   ...
   Description = $"{s.Description}-- £{s.Rate}"

Si vous projetez vers un nom de classe ViewModel fort (au lieu d'une classe anonyme), vous voudrez sans aucun doute remplacer les chaînes magiques par la sécurité du nameof opérateur:

ViewBag.StandID = new SelectList(stands, nameof(Stand.StandID), nameof(Stand.Description));
76
StuartLC
var stands = db.Stands.Where(s => s.ExhibitorID == null).ToList();
IEnumerable<SelectListItem> selectList = from s in stands
                                         select new SelectListItem
                                                    {
                                                      Value = s.StandID,
                                                      Text = s.Description + "-- £" + s.Rate.ToString()
                                                    };
ViewBag.StandID = new SelectList(selectList, "Value", "Text");
14
chridam

Vous pouvez créer une classe de modèle partielle

public partial class Stand
{
    public string DisplayName
    {
        get
        {
            return this.Description + "-- £" + this.Rate.ToString();
        }
    }

}

Puis dans votre vue

var stands = db.Stands.Where(s => s.ExhibitorID == null).ToList();
ViewBag.StandID = new SelectList(stands,"StandID", "DisplayName");
6
Guish

Le format du constructeur que vous utilisez est SelectList (éléments IEnumerable, string dataValueField, string dataTextField).

Donc, lorsque vous l'utilisez comme vous l'avez, vous lui dites de se lier au TextField appelé "Description - £ Rate" et si ce n'est pas ce que le champ est appelé venant de la DB, il ne saura pas ce que vous indiquent.

L'une des deux méthodes décrites ci-dessus fonctionnera tant que la valeur que vous avez dans votre dataValueField correspond au nom de la propriété dans laquelle vous mettez la valeur et que dataTextField correspond au nom de la propriété de l'endroit où vous placez le texte, peut-être un mélange des deux solutions ci-dessus. (Seulement parce que je préfère les expressions lambda à linq.) Et l'utilisation d'un élément selectlist l'empêche d'avoir à faire une ToList sur la collection après la transformation. vous créez en fait les objets qui se lient naturellement à une liste de sélection.

Vous pouvez également vouloir vérifier la description ou le taux pour vous assurer qu'ils ne sont pas vides avant de les mettre dans la liste

var stands = db.Stands.Where(s => s.ExhibitorID == null)
                  .Select(s => new SelectListItem
                {
                    Value = s.StandID.ToString(),
                    Text = s.Description + "-- £" + s.Rate.ToString()
                });


ViewBag.StandID = new SelectList(stands, "Value", "Text");
4
DRobertE

Je l'ai fait en modifiant mon View Model, voici mon code:

Le modèle de vue

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcEsosNew.Models;
using System.Web.Mvc;

namespace MvcEsosNew.ViewModels
{
    public class EntitlementViewModel
    {
        public int EntitlementCount { get; set; }
        public Entitlement Entitlement { get; set; }
        public SelectList Member { get; set; }
        public SelectList Job_Grade { get; set; }
        public SelectList Department { get; set; }
        public SelectList Esos_Batch { get; set; }
    }

    public class department_FullName
    {
        public int deptID { get; set; }
        public string deptCode { get; set; }
        public string deptName { get; set; }
        public string fullName { get { return deptCode + " - " + deptName; } }
    }
}

Le controlle

public void getAllDepartment(EntitlementViewModel entitlementVM)
        {
            var department = from Department in db.Departments.Where(D => D.Status == "ACTIVE").ToList()
                             select new department_FullName
                             {
                                 deptID   = Department.id,
                                 deptCode = Department.department_code,
                                 deptName = Department.department_name
                             };
            entitlementVM.Department = new SelectList(department, "deptID", "fullName");
        }

La vue

     <div class="form-group row">
                <div class="col-sm-2">
                    @Html.LabelFor(model => model.Entitlement.department_id)
                </div>
                <div class="col-sm-10">
                     @Html.DropDownListFor(model => model.Entitlement.department_id, Model.Department, new { @class="form-control" })
                     @Html.ValidationMessageFor(model => model.Entitlement.department_id)
                </div>
            </div>

Le résultat:

The Result

1
Ressa_Panda