C # DropDownList ze słownikiem jako źródłem danych

112

Chcę ustawić DataTextFieldi DataValueFieldz Dropdownlist(languageList) stosując słowniku (wykaz) languageCod(en-GB) jako klucz i nazwy języków (angielski) jako tekstu do wyświetlenia.

Odpowiedni kod:

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

Jak mogę ustawić DataTextFieldi DataValueField?

VansFannel
źródło

Odpowiedzi:

205

W ten sposób możesz ustawić DataTextField i DataValueField w DropDownList za pomocą tekstów „Klucz” i „Wartość”:

    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
źródło
12
Zalecam ustawienie TextField na „klucz” i ValueField na wartość. Myślę, że to bardziej intuicyjne.
MGOwen
15
@MGOwen Ustawienie wartości DataValueField na wartość może wydawać się intuicyjne ze względu na wspólną „wartość”, ale w rzeczywistości jest to nielogiczne przy regularnym korzystaniu z infrastruktury danych / kontroli. Aby uzyskać szczegółowe informacje, zobacz mój komentarz do odpowiedzi Jona Skeeta.
Dani
Nie widzę listy. Dodaj, który przyjmuje 2 argumenty .. tylko jeden, który przyjmuje jeden argument. czy to jest winforms ??
hrh
@hrh to prawdopodobnie nie używasz a Dictionary<TKey, TValue>, ale może List<T>.
pokaż
@Canavar czy można ustawić pole DataText jako „klucz-wartość” ....? Jak mogę to zrobić.
Sravan Kumar
11

Kiedy słownik jest wyliczany, zwróci KeyValuePair<TKey,TValue>obiekty ... więc wystarczy określić „Wartość” i „Klucz” odpowiednio dla DataTextFieldi DataValueField, aby wybrać właściwości Wartość / Klucz .

Dzięki komentarzowi Joe ponownie przeczytałem pytanie, aby ująć je we właściwy sposób. Normalnie oczekiwałbym, że „klucz” w słowniku będzie wyświetlanym tekstem, a „wartością” będzie pobrana wartość. Twój przykładowy kod używa ich jednak w drugą stronę. O ile naprawdę nie potrzebujesz ich w ten sposób, możesz rozważyć napisanie swojego kodu jako:

list.Add(cul.DisplayName, cod);

(A następnie , oczywiście, zmieniając powiązanie na „Klucz” dla DataTextFieldi „Wartość” dla DataValueField).

W rzeczywistości sugerowałbym, że ponieważ wydaje się, że naprawdę potrzebujesz listy, a nie słownika, możesz w pierwszej kolejności rozważyć ponowne użycie słownika. Możesz po prostu użyć 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));
}

Alternatywnie użyj listy zwykłych CultureInfowartości. LINQ sprawia, że ​​jest to naprawdę łatwe:

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

Jeśli nie używasz LINQ, nadal możesz używać normalnej pętli 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();
Jon Skeet
źródło
3
Właściwie to jest niepoprawne - zobacz mój komentarz do zaakceptowanej odpowiedzi.
Winston Smith
Ach, źle odczytałem pytanie. Umieszczanie ich w słowniku w „niewłaściwy” sposób wydaje mi się zagmatwane. Zmieni moją odpowiedź.
Jon Skeet
1
@JonSkeet Powodem powiązania „wstecznego” jest to, że dane przechowywane w słowniku jako para klucz / wartość zwykle używają klucza (wartości wyszukiwania) jako powiązania danych (np. Do odwoływania się do bazy danych) i na liście rozwijanej , odpowiada to DataValueField, tj. zwracanej wartości POST, która mówi więcej o wybranym elemencie niż DataTextField, czyli wartość wyświetlana. (DropDownLists mają po prostu kiepską konwencję nazewnictwa)
Dani,
6

Jeśli DropDownList jest zadeklarowana na stronie aspx, a nie w kodzie, możesz to zrobić w ten sposób.

.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
źródło
Głosowano za. Warto zauważyć, że WYMAGANE jest, aby był to obiekt po stronie serwera do oceny. Nie możesz przekazać tego w tekście przy użyciu <% # syntax%>. Niezależnie od tego, czy będzie to <script runat = "server">, czy jak widać w powyższym przykładzie Matta, zależy od Ciebie. To rzeczywiście działa.
Barry
5

Po prostu użyj „Klucz” i „Wartość”

user98296
źródło