C # DropDownList com um dicionário como fonte de dados

112

Desejo definir DataTextFielde DataValueFieldde a Dropdownlist(languageList) usando um Dicionário (lista) de languageCod(en-gb) como chave e o nome do idioma (inglês) como o texto a ser exibido.

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

Como posso definir DataTextFielde DataValueField?

VansFannel
fonte

Respostas:

205

Assim, você pode definir DataTextField e DataValueField de DropDownList usando os textos "Chave" e "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
fonte
12
Eu recomendo definir TextField como "chave" e ValueField como Value. Acho que é mais intuitivo.
MGOwen
15
@MGOwen Pode parecer intuitivo definir DataValueField como Value, por causa do "Value" comum, mas é realmente ilógico no uso regular da estrutura de dados / controle. Para detalhes sobre isso, veja meu comentário sobre a resposta de Jon Skeet.
Dani
Não vejo uma lista.Adicione que leva 2 argumentos .. apenas um que leva um arg. isso é winforms?
hora
@hrh então você provavelmente não está usando um Dictionary<TKey, TValue>, mas talvez um List<T>.
sshow
@Canavar é possível definir o campo DataText como "valor-chave" ....? Como eu posso fazer isso.
Sravan Kumar
11

Quando um dicionário é enumerado, ele produzirá KeyValuePair<TKey,TValue>objetos ... então você só precisa especificar "Valor" e "Chave" para DataTextFielde DataValueField, respectivamente, para selecionar as propriedades Valor / Chave .

Graças ao comentário de Joe, reli a pergunta para entendê-la da maneira certa. Normalmente, eu esperaria que a "chave" no dicionário fosse o texto exibido e o "valor" fosse o valor obtido. No entanto, seu código de amostra os usa ao contrário. A menos que você realmente precise que eles sejam assim, considere escrever seu código como:

list.Add(cul.DisplayName, cod);

(E depois alterando a vinculação para usar "Chave" DataTextFielde "Valor" DataValueField, é claro.)

Na verdade, eu sugeriria que, como parece que você realmente quer uma lista em vez de um dicionário, você pode querer reconsiderar o uso de um dicionário em primeiro lugar. Você pode simplesmente usar um 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));
}

Como alternativa, use uma lista de CultureInfovalores simples . LINQ torna isso realmente fácil:

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

Se você não estiver usando o LINQ, ainda poderá usar um loop 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
fonte
3
Na verdade, isso está incorreto - veja meu comentário sobre a resposta aceita.
Winston Smith
Ah, eu interpretei mal a pergunta. Parece-me confuso colocá-los em um dicionário da maneira "errada". Editará minha resposta.
Jon Skeet
1
@JonSkeet A razão para a associação "reversa" é que os dados sendo armazenados no dicionário como um par chave / valor normalmente usa a chave (valor de pesquisa) como uma associação de dados (por exemplo, para referência de banco de dados), e em uma lista suspensa , isso corresponde ao DataValueField, ou seja, o valor de retorno de um POST, que informa mais sobre o item selecionado do que o DataTextField, ou seja, o valor de exibição. (DropDownLists apenas tem uma convenção de nomenclatura pobre)
Dani
6

Se o DropDownList for declarado em sua página aspx e não no codebehind, você pode fazer assim.

.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
fonte
Votado. Vale ressaltar que é OBRIGATÓRIO que este seja um objeto do lado do servidor a ser avaliado. Você não pode transmiti-lo inline usando <% # syntax%>. Seja um <script runat = "server">, ou como visto no exemplo de Matt acima, depende de você. Isso realmente funciona.
Barry
5

Basta usar "Chave" e "Valor"

user98296
fonte