2011-01-26 2 views
14

Informazioni sugli elenchi a discesa, Sto cercando di aggiungere un RSVP per creare una pagina per nerddinner come in Scott Gu's blog con un Html.DropDownListPer elencare le cene disponibili.asp.net mvc 3 preselezione Html.DropDownListPer non lavorare nella cena per nerd

Posso ottenere l'elenco a discesa popolato ma non riesco a ottenere il menu a discesa per selezionare il valore ("Sample Dinner 2") che desidero. Sto usando un iniziatore per seminare alcuni oggetti per la cena nel db. Il database è in sql ce 4 che utilizza un "primo approccio al codice" EF. Mi dispiace che questo è av problema comune e odio a chiedere, ma onestamente ho passato un bel po 'di tempo su questo, ma non posso farlo funzionare:

ViewModel

public class RSVPViewModel 
{ 
    public SelectList DinnersList { get; set; } 
    public RSVP Rsvp { get; set; } 
    public string SelectedItem { get; set; } 
} 

controller

// 
    //GET: /RSVP/Create 

    public ActionResult Create() 
    { 
     RSVP rsvp = new RSVP(); 
     string selected = "Sample Dinner 2"; 
     var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title", selected); 

     var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp, SelectedItem = selected }; 

     return View("Create", viewModel); 
    } 

View

@Html.DropDownListFor(model => model.Rsvp.DinnerID, Model.DinnersList) 

Risultato HTML

<select data-val="true" data-val-number="The field DinnerID must be a number." data-val-required="The DinnerID field is required." id="Rsvp_DinnerID" name="Rsvp.DinnerID"> 
    <option value="1">Sample Dinner 1</option> 
    <option value="2">Sample Dinner 2</option> 
</select> 

Quindi non è la preselezione DropDownList con il valore "Sample Dinner 2" al caricamento della pagina. L'elenco viene visualizzato correttamente e imposta il DinnerID corretto quando effettuo una selezione e fai clic su Invia.

Tentativi questo anche:

@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList) 

ma pretende molto impostati o legarsi a Rsvp.DinnerID.

Questa preseleziona dalla lista, ma pretende molto bind (o impostare Rsvp.DinnerID)

@Html.DropDownList("DinnersList") 

voglio tenerlo MVC3 così vuole implementare con il tipo di forte utilizzando approccio ViewModel (senza Viewdata) e preferibilmente utilizzando Html .DropDownListFor (non Html.DropDownList) .Viewbag non sembra necessario per questo caso.

Grazie!

Edit1

Pensare dovrei usare un SelectList di selectListItems ho provato questo approccio verbose:

RSVP rsvp = new RSVP(); 
string selected = "2"; 
List<SelectListItem> dinners = new List<SelectListItem>(); 

foreach (Dinner dinner in dbc.Dinners.ToList()) 
{ 
    SelectListItem slDinner = new SelectListItem(); 
    slDinner.Value = dinner.DinnerID.ToString(); 
    slDinner.Text = dinner.Title; 
    slDinner.Selected = (slDinner.Value == selected); 
    dinners.Add(slDinner); 
} 

var dinnersList = new SelectList(dinners, "Value", "Text", selected); 
var viewModel = new RSVPViewModel { DinnersList = dinnersList, Rsvp = rsvp, SelectedItem = selected }; 

Tuttavia ancora nessun lavoro. Dovrei usare la proprietà ViewModel SelectedItem in: @ Html.DropDownListFor .. in qualche modo? Qualcosa di simile:

@Html.DropDownListFor(x => x.SelectedItem, Model.DinnersList) 

ma come ottenere un valore selezionato per impostare Rsvp.DinnerID. Penso che questo sia chiamato vincolante.

+0

Quando si passa tramite il codice, fa la lista prodotta da 'nuova SelectList (...)' hanno un oggetto la cui proprietà Selected è vera? – StriplingWarrior

+0

Non sono sicuro di cosa intendi. Non sto usando SelectListItems nella selectlist in modo da non vedere la proprietà selezionata? Ho anche letto altrove (http://stackoverflow.com/questions/2410543/dropdownlist-setting-selected-item-in-asp-net-mvc) che la proprietà Selected viene ignorata nella maggior parte dei casi (forse potrebbe funzionare per @ html.dropdownlist ("Lista cena"), ma non ha alcun legame? – Jay

+0

Posso vedere una proprietà 'SelectedValue' in typeList il cui valore è 2 e il tipo è int dopo aver modificato la risposta in basso. – Jay

risposta

12

Dopo aver letto here e here, ho finalmente capito come HtmlDropDownlistFor seleziona automaticamente l'articolo corretto nel menu a discesa in base al modello - la selezione di un dinnerID a RSVP (chiave esterna per la cena. dinnerID) farà sì che il menu a discesa contenente l'elenco di Dinner.DinnerIDs pre-selezionare tale valore. Non è necessario eppure Penso per SelectedValue in SelectList o ViewModel.

Soluzione:

// 
    //GET: /RSVP/Create 

    public ActionResult Create() 
    { 
     //automatically preselects matching DinnerID in the Dinner dropdownlist    
     var rsvp = new RSVP {DinnerID = 2 }; 

     var typeList = new SelectList(dbc.Dinners.ToList(), "DinnerID", "Title"); 
     var viewModel = new RSVPViewModel { DinnersList = typeList, Rsvp = rsvp}; 

     return View("Create", viewModel); 
    } 
+0

Vedere le mie esercitazioni DDL http://www.asp.net/mvc/tutorials/javascript/working-with-the-dropdownlist -box-and-jquery/using-the-dropdownlist-helper-with-aspnet-mvc e http://blogs.msdn.com/b/rickandy/archive/2012/01/09/cascasding-dropdownlist-in-asp -net-mvc.aspx – RickAndMSFT

3

Il SelectList constructor che si sta utilizzando dovrebbe fornire il valore selezionato, ma si sta fornendo il testo selezionato.Si consiglia di provare:

int selected = 2; 
+1

Anche questo non ha funzionato. l'elenco. Ho controllato il db per assicurarmi che ci fosse un oggetto per la cena con DinnerID = 2 presente anche – Jay

2

Html.DropDownList funziona solo se la proprietà vincolati è un int. Qualsiasi altro tipo, ad esempio un enum con nome, lo porterà al valore predefinito sul primo elemento.

aggiunge una proprietà al modello, tipo int, che avvolge l'enumerazione che si sta tentando di mantenere:

public myEnumType myProperty {get; set;} // don't bind this to Html.DropDownList 

public myEnumType myPropertyAsInt { 
    get {return (int)this.myProperty; } 
    set {this.myProperty = (myEnumType)value; } 
} // bind this instead 

alcun bisogno di usare selezionato nel SelectList - Html.DropDownList si sincronizzerà più che bene.

+2

Questo non è corretto Vedi le mie esercitazioni DDL http://www.asp.net/mvc/tutorials/javascript/working-with-the-dropdown list-box-and-jquery/using-the-dropdownlist-helper-with-aspnet-mvc e http://blogs.msdn.com/b/rickandy/archive/2012/01/09/cascasding-dropdownlist-in- asp-net-mvc.aspx – RickAndMSFT

+0

Questo ha funzionato per me, inizialmente stavo legando a enum ma la conversione a un collegamento int in questo esempio ha causato la preselezione di un elemento per funzionare – Neil

1

Html.DropDownList accetta proprietà int, DropDownListFor, ma è necessario fare attenzione a ciò che si sta facendo. Ho esaminato SelectExtensions.cs da ASP.NET MVC 3 e ho rilevato:

Quando si utilizza DropDownList ("XyField", "default") per creare un DropDown, è necessario posizionare l'elenco di selezione in ViewBag.XyField e DropDownList() gestisce questo correttamente.

Quando si utilizza DropDownListFor (m => m.XyField, ...), è possibile passare alla lista di selezione esplicitamente, in questo modo:.. DropDownListFor (m => m XyField, ViewBag XyFieldList come IEnumerable)

Quando si esegue questa operazione, questa seguente accada:

  • Il secondo parametro di DropDownListFor (...) saranno utilizzati come fonte per le opzioni
  • Se c'è una voce ModelState per " Xy Campo ", verrà utilizzato come valore del modello
  • Se non esiste uno stato del modello E Html.ViewData.Eval (" XyField ") non restituisce null, questo valore verrà utilizzato come valore del modello.
  • Se il valore del modello trovato non è nullo, verrà convertito in una stringa, utilizzando CultureInfo.CurrentCulture e questo valore viene confrontato con i valori di SelectListItem per preselezionare le opzioni dell'elenco.

Attenzione: se è stato archiviato l'elenco di selezione in ViewBag.XyField, verrà trovato prima dell'accesso del modello. Non si desidera confrontare "selectList.ToString()" con "selectList [i] .Value" per preselezionare le opzioni. Salva la tua lista di selezione in un altro posto!

La cosa divertente è che è possibile utilizzare DropDownListFor con un elenco di selezione implicito, nello stesso modo in cui ci si aspetta da DropDownList(). In questo caso, memorizzerai anche la tua lista in ViewBag.XyField. Per fare in modo che funzioni, è sufficiente chiamare l'helper con null come secondo parametro: DropDownListFor (m => m.XyField, null)

Quindi, l'elenco di selezione viene estratto da ViewBag.XyField e il passaggio 3 nell'elenco sopra viene saltato. Quindi, se XyField si trova nello stato del modello, questo avrà la precedenza prima delle tue proprietà selezionate nell'elenco di selezione, ma in caso contrario, l'elenco di selezione verrà utilizzato "così com'è".

Saluti Rolf

2

prega di fare attenzione se v'è uno STRING QUERY con stesso nome, sarà ignorare che il comportamento, Non sei sicuro di campi nascosti con lo stesso nome.

E.g.

DropDownListFor userà il valore della stringa di query di DinnerID se trovato