C # DropDownList con un diccionario como fuente de datos

112

Quiero establecer DataTextFieldy DataValueFieldde un Dropdownlist(languageList) usando un Diccionario (lista) de languageCod(en-gb) como clave y el nombre del idioma (inglés) como texto para mostrar.

Código relevante:

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

¿Cómo puedo configurar DataTextFieldy DataValueField?

VansFannel
fuente

Respuestas:

205

De esa manera, puede configurar DataTextField y DataValueField de DropDownList usando los textos "Clave" y "Valor":

    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();
Canavar
fuente
12
Recomiendo configurar TextField en "clave" y ValueField en Value. Creo que es más intuitivo.
MGOwen
15
@MGOwen Puede parecer intuitivo establecer DataValueField en Value, debido al "Value" común, pero en realidad es ilógico en el uso regular de la estructura de datos / control. Para obtener detalles sobre esto, vea mi comentario sobre la respuesta de Jon Skeet.
Dani
No veo una lista. Agregue que toma 2 argumentos .. solo uno que toma un argumento. es esto winforms ??
hr
@hrh, entonces probablemente no estés usando a Dictionary<TKey, TValue>, pero tal vez a List<T>.
Mostrar
@Canavar ¿es posible establecer el campo DataText como "valor-clave" ....? Cómo puedo hacerlo.
Sravan Kumar
11

Cuando se enumera un diccionario, producirá KeyValuePair<TKey,TValue>objetos ... por lo que solo necesita especificar "Valor" y "Clave" para DataTextFieldy DataValueField, respectivamente, para seleccionar las propiedades Valor / Clave .

Gracias al comentario de Joe, releí la pregunta para resolverlas correctamente. Normalmente, esperaría que la "clave" en el diccionario sea el texto que se muestra y el "valor" sea el valor obtenido. Sin embargo, su código de muestra los usa al revés. A menos que realmente los necesite de esta manera, es posible que desee considerar escribir su código como:

list.Add(cul.DisplayName, cod);

(Y luego cambiar el enlace para usar "Clave" para DataTextFieldy "Valor" para DataValueField, por supuesto).

De hecho, sugiero que, como parece que realmente desea una lista en lugar de un diccionario, es posible que desee reconsiderar el uso de un diccionario en primer lugar. Podrías usar 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));
}

Alternativamente, use una lista de CultureInfovalores simples . LINQ lo hace realmente fácil:

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

Si no está usando LINQ, aún puede usar un bucle foreach normal:

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();
Jon Skeet
fuente
3
En realidad, esto es incorrecto; vea mi comentario sobre la respuesta aceptada.
Winston Smith
Ah, leí mal la pregunta. Me parece confuso ponerlos en un diccionario al revés. Editaré mi respuesta.
Jon Skeet
1
@JonSkeet La razón de la asociación "hacia atrás" es que los datos que se almacenan en el diccionario como un par clave / valor normalmente usan la clave (valor de búsqueda) como una asociación de datos (por ejemplo, para referenciar la base de datos) y en una lista desplegable , esto corresponde al DataValueField, es decir, el valor de retorno de un POST, que le dice más sobre el elemento seleccionado que el DataTextField, es decir, el valor de visualización. (Las listas desplegables tienen una convención de nomenclatura deficiente)
Dani
6

Si DropDownList se declara en su página aspx y no en el código subyacente, puede hacerlo así.

.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
    }
};
Matt Frear
fuente
Voto a favor. Es de destacar que se REQUIERE que este sea un objeto del lado del servidor para ser evaluado. No puede pasarlo en línea usando <% # syntax%>. Ya sea un <script runat = "server">, o como se ve en el ejemplo de Matt anterior, depende de usted. De hecho funciona.
Barry
5

Simplemente use "Clave" y "Valor"

user98296
fuente