2008-09-25 9 views
10

Ho un tale aspx-code: (campione)Aggiunta ListItems ad una DropDownList da un elenco generico

<asp:DropDownList runat="server" ID="ddList1"></asp:DropDownList> 

Con questo codebehind:

List<System.Web.UI.WebControls.ListItem> colors = new List<System.Web.UI.WebControls.ListItem>(); 
colors.Add(new ListItem("Select Value", "0")); 
colors.Add(new ListItem("Red", "1")); 
colors.Add(new ListItem("Green", "2")); 
colors.Add(new ListItem("Blue", "3")); 
ddList1.DataSource = colors; 
ddList1.DataBind(); 

L'output è simile al seguente:

<select name="ddList1" id="ddList1"> 
    <option value="Select Value">Select Value</option> 
    <option value="Red">Red</option> 
    <option value="Green">Green</option> 
    <option value="Blue">Blue</option> 
</select> 

La mia domanda è: perché i miei valori (numeri) sono scomparsi e il testo utilizzato come valore E il testo? So che funziona se uso il metodo ddList1.Items.Add(New ListItem("text", "value")), ma ho bisogno di utilizzare un elenco generico come origine dati per altri motivi.

risposta

10

Poiché il metodo DataBind esegue il bind dei valori solo se è impostata la proprietà DataValueField. Se si imposta la proprietà DataValueField su "Value" prima di chiamare DataBind, i valori verranno visualizzati nel markup.

AGGIORNAMENTO: Sarà inoltre necessario impostare la proprietà DataTextField su "Testo". È perché il collegamento dei dati e l'aggiunta manuale degli elementi non funzionano allo stesso modo. L'associazione dati non conosce l'esistenza di tipo ListItem e genera markup valutando gli elementi nell'origine dati.

+0

Perché si _need_ per impostare quel campo? Come ho detto, funziona quando ListItem viene aggiunto direttamente alla raccolta DropDownList.Items. Ho provato il tuo suggerimento e non ha aiutato. Vedi la mia domanda aggiornata. – Espo

+0

Vedo. Ho aggiornato la risposta e aggiunto le informazioni per risolverlo. –

+0

Funziona, grazie! – Espo

3

E qui è il metodo che esegue il binding dei dati. Si può vedere esattamente cosa sta succedendo:

protected internal override void PerformDataBinding(IEnumerable dataSource) 
{ 
    base.PerformDataBinding(dataSource); 
    if (dataSource != null) 
    { 
     bool flag = false; 
     bool flag2 = false; 
     string dataTextField = this.DataTextField; 
     string dataValueField = this.DataValueField; 
     string dataTextFormatString = this.DataTextFormatString; 
     if (!this.AppendDataBoundItems) 
     { 
      this.Items.Clear(); 
     } 
     ICollection is2 = dataSource as ICollection; 
     if (is2 != null) 
     { 
      this.Items.Capacity = is2.Count + this.Items.Count; 
     } 
     if ((dataTextField.Length != 0) || (dataValueField.Length != 0)) 
     { 
      flag = true; 
     } 
     if (dataTextFormatString.Length != 0) 
     { 
      flag2 = true; 
     } 
     foreach (object obj2 in dataSource) 
     { 
      ListItem item = new ListItem(); 
      if (flag) 
      { 
       if (dataTextField.Length > 0) 
       { 
        item.Text = DataBinder.GetPropertyValue(obj2, dataTextField, dataTextFormatString); 
       } 
       if (dataValueField.Length > 0) 
       { 
        item.Value = DataBinder.GetPropertyValue(obj2, dataValueField, null); 
       } 
      } 
      else 
      { 
       if (flag2) 
       { 
        item.Text = string.Format(CultureInfo.CurrentCulture, dataTextFormatString, new object[] { obj2 }); 
       } 
       else 
       { 
        item.Text = obj2.ToString(); 
       } 
       item.Value = obj2.ToString(); 
      } 
      this.Items.Add(item); 
     } 
    } 
    if (this.cachedSelectedValue != null) 
    { 
     int num = -1; 
     num = this.Items.FindByValueInternal(this.cachedSelectedValue, true); 
     if (-1 == num) 
     { 
      throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" })); 
     } 
     if ((this.cachedSelectedIndex != -1) && (this.cachedSelectedIndex != num)) 
     { 
      throw new ArgumentException(SR.GetString("Attributes_mutually_exclusive", new object[] { "SelectedIndex", "SelectedValue" })); 
     } 
     this.SelectedIndex = num; 
     this.cachedSelectedValue = null; 
     this.cachedSelectedIndex = -1; 
    } 
    else if (this.cachedSelectedIndex != -1) 
    { 
     this.SelectedIndex = this.cachedSelectedIndex; 
     this.cachedSelectedIndex = -1; 
    } 
} 
+0

Grazie. Penso che avere "Testo" e "Valore" come proprietà predefinite sia una buona idea. – Espo

3

Se si sta costruendo ListItems, non avete bisogno di usare DataBind() in primo luogo.

Basta aggiungere al vostro DropDownList:



ddList1.Items.Add(new ListItem("Select Value", "0")); 
ddList1.Items.Add(new ListItem("Red", "1")); 
ddList1.Items.Add(new ListItem("Green", "2")); 
ddList1.Items.Add(new ListItem("Blue", "3")); 

DataBind() è utile quando si dispone già di una collezione/DataObject (di solito un DataTable o DataView) che può essere utilizzato come un DataSource, impostando il DataTextField e DataValueField (come scritto da buyutec).

+0

Grazie per il tuo commento, anche se non ha risposto secondo la sua ultima frase. Non avevo capito che era tutto ciò di cui avevo bisogno. – Bryan

1

"Se si sta creando ListItems, non è necessario utilizzare DataBind() in primo luogo."

Aggiungere direttamente alla lista a discesa è il modo semplice (e dato il codice di esempio quello giusto) ma diciamo che hai un'origine dati non ordinata e vuoi ordinare gli elementi della lista.

Un modo per ottenere ciò sarebbe quello di creare un elenco generico di ListItem e quindi utilizzare il metodo di ordinamento ereditato prima del collegamento ai dati nell'elenco.

Ci sono molte ragioni per dare la pelle a un gatto ...