2008-09-25 7 views
10

J'ai ce ASPX code: (exemple)Ajout ListItems à un DropDownList à partir d'une liste générique

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

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

La sortie ressemble à ceci:

<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> 

Ma question est: Pourquoi mes valeurs (nombres) ont-elles disparu et le texte utilisé comme valeur ET le texte? Je sais que cela fonctionne si j'utilise la méthode ddList1.Items.Add(New ListItem("text", "value")), mais j'ai besoin d'utiliser une liste générique comme source de données pour d'autres raisons.

Répondre

10

Parce que la méthode DataBind lie les valeurs uniquement si la propriété DataValueField est définie. Si vous définissez la propriété DataValueField sur "Value" avant d'appeler DataBind, vos valeurs apparaîtront sur le balisage.

MISE À JOUR: Vous devrez également définir la propriété DataTextField sur "Texte". C'est parce que la liaison de données et l'ajout manuel d'éléments ne fonctionnent pas de la même manière. La liaison de données ne connaît pas l'existence de type ListItem et génère un balisage en évaluant les éléments dans la source de données.

+0

Pourquoi ai-je besoin de définir ce champ? Comme je l'ai dit, cela fonctionne quand le ListItem est ajouté directement à la collection DropDownList.Items. J'ai essayé votre suggestion et cela n'a pas aidé. Voir ma question mise à jour. – Espo

+0

Je vois. J'ai mis à jour la réponse et ajouté l'information pour corriger cela. –

+0

Ça marche, merci! – Espo

3

Et voici la méthode qui effectue la liaison de données. Vous pouvez voir exactement ce qui se passe:

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

Merci. Je pense qu'avoir "Texte" et "Valeur" comme propriétés par défaut est une bonne idée. – Espo

3

Si vous construisez ListItems, vous n'avez pas besoin d'utiliser DataBind() en premier lieu.

Il suffit de les ajouter à votre 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() est utile lorsque vous avez déjà une collection/dataobject (généralement un DataTable ou DataView) qui peut être utilisé comme source de données, en définissant le DataTextField et DataValueField (comme écrit par buyutec).

+0

Merci pour votre commentaire, même s'il n'a pas répondu selon sa dernière phrase. Je n'avais pas réalisé que c'était tout ce que je devais faire. – Bryan

1

"Si vous développez ListItems, vous n'avez pas besoin d'utiliser DataBind() en premier lieu."

Ajouter directement à la liste déroulante est la manière facile (et donné le code d'exemple le bon), mais disons que vous avez une source de données non ordonnée et que vous voulez trier les éléments de la liste. Pour ce faire, vous pouvez créer une liste générique de ListItem, puis utiliser la méthode de tri héritée avant de lier la liste à une liste.

Il ya beaucoup de wys pour habiller un chat ...

Questions connexes