C # DropDownList con un dizionario come DataSource


112

Voglio impostare DataTextFielde DataValueFielddi un Dropdownlist(languageList) utilizzando un Dictionary (list) di languageCod(en-gb) come chiave e il nome della lingua (inglese) come testo da visualizzare.

Codice pertinente:

string[] languageCodsList= service.LanguagesAvailable();
Dictionary<string, string> list = 
                   new Dictionary<string, string>(languageCodsList.Length);

foreach (string cod in languageCodsList)
{
    CultureInfo cul = new CultureInfo(cod);
    list.Add(cod, cul.DisplayName);
}
languageList.DataSource = list;
languageList.DataBind();

Come posso impostare DataTextFielde DataValueField?

Risposte:


205

In questo modo puoi impostare DataTextField e DataValueField di DropDownList utilizzando i testi "Key" e "Value":

    Dictionary<string, string> list = new Dictionary<string, string>();
    list.Add("item 1", "Item 1");
    list.Add("item 2", "Item 2");
    list.Add("item 3", "Item 3");
    list.Add("item 4", "Item 4");

    ddl.DataSource = list;
    ddl.DataTextField = "Value";
    ddl.DataValueField = "Key";
    ddl.DataBind();

12
Suggerirei di impostare TextField su "key" e ValueField su Value. Penso che sia più intuitivo.
MGOwen

15
@MGOwen Può sembrare intuitivo impostare DataValueField su Value, a causa del comune "Value", ma in realtà è illogico nell'uso regolare della struttura / controllo dati. Per i dettagli su questo, vedere il mio commento sulla risposta di Jon Skeet.
Dani

Non vedo una lista. Aggiungi che richiede 2 argomenti .. solo uno che richiede un argomento. è questo winforms ??
hrh

@hrh allora probabilmente non stai usando a Dictionary<TKey, TValue>, ma forse a List<T>.
spettacolo

@Canavar è possibile impostare il campo DataText come "valore-chiave" ....? Come posso farlo.
Sravan Kumar

11

Quando un dizionario viene enumerato, produrrà KeyValuePair<TKey,TValue>oggetti ... quindi è sufficiente specificare "Valore" e "Chiave" rispettivamente per DataTextFielde DataValueFieldper selezionare le proprietà Valore / Chiave .

Grazie al commento di Joe, ho riletto la domanda per ottenerli nel modo giusto. Normalmente mi aspetto che la "chiave" nel dizionario sia il testo visualizzato e il "valore" sia il valore recuperato. Tuttavia, il codice di esempio li utilizza al contrario. A meno che tu non abbia davvero bisogno che siano in questo modo, potresti prendere in considerazione la possibilità di scrivere il tuo codice come:

list.Add(cul.DisplayName, cod);

(E poi cambiando l'associazione per usare "Chiave" per DataTextFielde "Valore" per DataValueField, ovviamente.)

In effetti, suggerirei che, poiché sembra che tu voglia davvero un elenco piuttosto che un dizionario, potresti voler riconsiderare l'utilizzo di un dizionario in primo luogo. Potresti semplicemente usare un List<KeyValuePair<string, string>>:

string[] languageCodsList = service.LanguagesAvailable();
var list = new List<KeyValuePair<string, string>>();

foreach (string cod in languageCodsList)
{
    CultureInfo cul = new CultureInfo(cod);
    list.Add(new KeyValuePair<string, string>(cul.DisplayName, cod));
}

In alternativa, utilizza un elenco di CultureInfovalori semplici . LINQ lo rende davvero semplice:

var cultures = service.LanguagesAvailable()
                      .Select(language => new CultureInfo(language));
languageList.DataTextField = "DisplayName";
languageList.DataValueField = "Name";
languageList.DataSource = cultures;
languageList.DataBind();

Se non stai usando LINQ, puoi comunque usare un normale ciclo foreach:

List<CultureInfo> cultures = new List<CultureInfo>();
foreach (string cod in service.LanguagesAvailable())
{
    cultures.Add(new CultureInfo(cod));
}
languageList.DataTextField = "DisplayName";
languageList.DataValueField = "Name";
languageList.DataSource = cultures;
languageList.DataBind();

3
In realtà, questo non è corretto - vedi il mio commento sulla risposta accettata.
Winston Smith

Ah, avrei letto male la domanda. Mi sembra confuso metterli in un dizionario nel modo "sbagliato". Modificherò la mia risposta.
Jon Skeet

1
@JonSkeet Il motivo dell'associazione "all'indietro" è che i dati archiviati nel dizionario come coppia chiave / valore normalmente utilizza la chiave (valore di ricerca) come associazione di dati (ad es. Per riferimenti al database) e in un elenco a discesa , questo corrisponde al DataValueField, cioè il valore di ritorno di un POST, che fornisce maggiori informazioni sull'elemento selezionato rispetto al DataTextField, ovvero il valore visualizzato. (DropDownLists ha solo una convenzione di denominazione scadente)
Dani

6

Se DropDownList è dichiarato nella tua pagina aspx e non nel codebehind, puoi farlo in questo modo.

aspx:

<asp:DropDownList ID="ddlStatus" runat="server" DataSource="<%# Statuses %>"
     DataValueField="Key" DataTextField="Value"></asp:DropDownList>

.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
{
    ddlStatus.DataBind();
    // or use Page.DataBind() to bind everything
}

public Dictionary<int, string> Statuses
{
    get 
    {
        // do database/webservice lookup here to populate Dictionary
    }
};

Upvoted. È interessante notare che è RICHIESTO che questo sia un oggetto lato server da valutare. Non puoi passarlo in linea usando <% # syntax%>. Che sia uno <script runat = "server">, o come visto nell'esempio di Matt sopra, dipende da te. Funziona davvero.
Barry

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.