IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

FAQ ASP.NET/VB.NET

FAQ ASP.NET/VB.NETConsultez toutes les FAQ

Nombre d'auteurs : 38, nombre de questions : 369, dernière mise à jour : 16 juin 2021 

 
OuvrirSommaireWebFormsContrôlesContrôles serveur (WebControl)Contrôles standardsDropDownList

Ce problème est trés récurent. Dans 99% des cas le problème vient du postback :
Si vous remplissez votre dropdownlist dans le "Page_Load" de votre page, le code correct est :

 
Sélectionnez
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    If not Page.IsPostBack Then
       'code pour remplir la dropdownlist
    End If
End Sub

L'erreur fréquement comise est d'oublier le "If not page.IsPostBack then" quand vous sélectionnez un objet de la dropdownlist, la page se recharge en faisant un postback, donc repasse par le "Page_Load et reinitialise votre dropdownlist. On spécifie donc qu'il ne faut pas reinitialiser la dropdownlist en cas de PostBack et on récupèrera ainsi la valeur sélectionnée.

Créé le 12 octobre 2003  par David Pedehourcq

Il arrive fréquemment que l'on remplisse une DropDownList avec les valeurs qui sont à afficher. Par contre, les valeurs sont souvent oubliées lors de cette initialisation.
Si l'initialisation se fait à l'aide d'un DataSet, rien de plus simple, il suffit de spécifier quel est le champ qui permettra de récupérer la valeur:

 
Sélectionnez
NomDropDownList.DataSource = DbTemplate.GetCategories
NomDropDownList.DataTextField = "champ_a_afficher"
NomDropDownList.DataValueField = "champ_valeur"
NomDropDownList.DataBind

Si l'initialisation se fait par l'ajout manuel d'Items, il suffit de créer des Items en spécifiant les deux valeurs.

 
Sélectionnez
Dim li As ListItem = New ListItem
li.Text = "texte"
li.Value = "valeur"
NomDropDownList.Items.Add(li)
Créé le 19 juin 2005  par Didier Danse

Vous pouvez ajouter un Item directement en utilisant Items.Add. Le premier paramètre correspond à l'emplacement (en l'occurrence 0) :

 
Sélectionnez
ddl.Items.insert(0,"mon texte")

Cependant, cette solution ne fait qu'afficher un texte. Si vous souhaitez passer un texte ainsi que la valeur correspondante, il est nécessaire d'utiliser un objet ListItem :

 
Sélectionnez
Dim li as ListItem=New ListItem("mon texte", "ma valeur")
ddl.Items.Insert(0, li)
Créé le 14 novembre 2007  par Didier Danse

Pour ajouter un élément à la collection Items d'une DropDownList il existe la fonction Add, mais celle-ci l'ajoute à la fin. Si on ne veut pas l'ajouter à la fin, il faut utiliser la fonction Insert :

 
Sélectionnez
MyDropDownList.Items.Insert(0, new ListItem("2 CV", "Voiture"))

Le code ci-dessus insérera l'élément "2 CV" et sa valeur "Voiture" à la position 0 de collection Items de la DropDownList

Créé le 19 juin 2005  par krest

Lien : Fonction Insert

L'erreur la plus fréquente est d'oublier de mettre à true la propriété AutoPostBack. Ce qui donne:

 
Sélectionnez
<asp:DropDownList runat=server id=IdDdl AutoPostBack=true>...</asp:DropDownList>

Si la propriété est à true, lorsque l'on sélectionne une autre valeur, la page est renvoyée au serveur.

Attention de ne pas réinitialiser la valeur sélectionnée dans le Page_Load.

Créé le 23 mai 2005  par Didier Danse

Lien : Ma dropdownlist est bien remplie, mais quand je sélectionne un item, c'est toujours la première valeur de la liste qui est retournée

Cela peut arriver si vous avez positionné EnableViewState à false sur votre page. Certaines stratégies d'entreprises prônent de ne pas utiliser le viewstate, pour certaines raisons compréhensibles que je ne détaillerai pas ici, et encouragent à récupérer les valeurs dans tout postback.
Mais cela pose un problème lorsqu'on veut utiliser les événements accessibles lorsqu'autopostback vaut true.
Imaginons une page toute simple (du code a été omis pour plus de clarté) où EnableViewState vaut false :

 
Sélectionnez
<%@ Page Language="vb" EnableViewState="false" AutoEventWireup="false" CodeBehind="Default.aspx.cs" Inherits="testDropdown.Default" %> 
		 
<asp:DropDownList ID="myDropDown" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ItemChange"> 
	<asp:ListItem Value="valeur1" Text="valeur1" /> 
	<asp:ListItem Value="valeur2" Text="valeur2" /> 
	<asp:ListItem Value="valeur3" Text="valeur3" /> 
</asp:DropDownList> 
<asp:Label ID="myLabel" runat="server" />

et dans le code behind

 
Sélectionnez
Protected Sub ItemChange(ByVal sender As Object, ByVal e As EventArgs)
	myLabel.Text = String.Format("Valeur selectionnée : {0}", sender.SelectedValue)
End Sub

Si l'on sélectionne les valeurs 2 ou 3, le texte est correctement affiché car on est passé correctement dans l'événement. Par contre, si on rebascule sur la valeur 1, rien n'est affiché, on ne passe pas dans l'événement.
En effet, comme le viewstate n'est pas utilisé, asp.net croit que c'est la valeur 1 qui est sélectionnée, et quand on la resélectionne après un premier changement, il en déduit que la valeur n'a pas changée, donc, il ne lève pas l'événement (le brigand).
La solution est donc de lever l'événement nous même, en surchargeant le OnLoad.

 
Sélectionnez
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
	If IsPostBack Then
		' on lève l'évenement si le postback a été déclenché par notre dropdown 
		Dim ctlName As String = Request.Params.Get("__EVENTTARGET")
		If Not String.IsNullOrEmpty(ctlName) Then
			If ctlName.Contains(myDropDown.ID) Then
				ItemChange(myDropDown, New EventArgs())
			End If
		End If
	End If
	MyBase.OnLoad(e)
End Sub

Protected Sub ItemChange(ByVal sender As Object, ByVal e As EventArgs)
	myLabel.Text = String.Format("Valeur selectionnée : {0}", sender.SelectedValue)
End Sub

Et au final, nous n'avons plus besoin de définir OnSelectedIndexChanged="ItemChange" comme attribut de <asp:DropDownList>

NB : Si on veut, il est bien sur possible de changer le prototype de la méthode ItemChange, vu qu'elle n'est plus levée par Asp.Net

 
Sélectionnez
Private Sub ItemChange(ByVal list As DropDownList, ByVal e As EventArgs)
End Sub
Créé le 10 mars 2008  par nico-pyright(c)

Comment faire pour lever un événement de changement lorsqu'une dropdown se repete X fois dans un repeater ?
Pour ce faire, nous allons déjà construire notre repeater.
Dans la page, on aura par exemple notre repeater, une dropdownlist par item et un label en dehors de ce repeater pour afficher la sélection :

 
Sélectionnez
<asp:Repeater runat="server" OnItemCreated="ItemCreated" ID="MonRepeater"> 
	<ItemTemplate> 
		<asp:DropDownList runat="server" ID="LaList" AutoPostBack="true" /> 
	</ItemTemplate> 
</asp:Repeater> 
<asp:Label runat="server" ID="LeLabel" />

Pour initialiser notre repeater, rien de tel qu'une bonne liste de liste

 
Sélectionnez
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
	EnableViewState = False
	Dim list As New List(Of List(Of String))
    Dim list1 As New List(Of String)
    list1.Add("abc")
    list1.Add("def")
    list1.Add("ghi")
    Dim list2 As New List(Of String)
    list2.Add("123")
    list2.Add("456")
    list2.Add("789")
    list.Add(list1)
    list.Add(list2)

    MonRepeater.DataSource = list
    MonRepeater.DataBind()
    MyBase.OnInit(e)
End Sub

Pour bien montrer qu'on ne se servira pas du viewstate, on le met explicitement à false dans le OnInit
Et dans l'événement du ItemCreated, on construit la dropdown à partir de la liste :

 
Sélectionnez
Protected Sub ItemCreated(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
	Dim list As DropDownList = e.Item.FindControl("LaList")
    list.Items.Add("choisir ...")
    For Each element As String In e.Item.DataItem
        list.Items.Add(element)
    Next
End Sub

Si on execute la page, on a donc 2 dropdownlist remplies respectivement des valeurs "choisir ...", "abc", "def", "ghi" et "choisir ...", "123", "456", "789".
Passons maintenant à la propagation de l'événement, toujours en surchargeant le OnLoad, juste après le base.OnLoad :

 
Sélectionnez
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
	MyBase.OnLoad(e)
	If IsPostBack Then
		Dim ctlName As String = Request.Params.Get("__EVENTTARGET")
        If Not String.IsNullOrEmpty(ctlName) Then
            ' on va chercher la dropdown qui a déclenché le postback dans __EVENTTARGET 
            For Each item As RepeaterItem In MonRepeater.Items
                Dim clientId As String = item.ClientID ' utilisé pour avoir la propriété ID, sinon elle vaudra null 
                Dim currentDropDown As DropDownList = item.FindControl("LaList")
                Dim dropDownName As String = String.Format("{0}${1}", item.ID, currentDropDown.ID)
                If ctlName.Contains(dropDownName) Then
                    ItemChange(currentDropDown, New EventArgs())
                End If
            Next
        End If
    End If
End Sub

Le principe est de parcourir les items du repeater et de concatener l'id de l'item à celle de la dropdownlist en mettant un $ entre les deux ; c'est grâce à ces deux valeurs qu'on pourra identifier de manière unique la dropdown qui a déclenché le postback.
ctlName vaudra "MonRepeater$ctl00$LaList"
et dropDownName vaudra "ctl00$LaList"

Une fois la dropdown identifiée, il n'y a plus qu'à simuler l'événement ItemChange, qui ici, nous affichera le résultat choisi dans le label

 
Sélectionnez
Sub ItemChange(ByVal list As DropDownList, ByVal args As EventArgs)
	LeLabel.Text = list.SelectedValue
End Sub

Voilà pour la dropdownlist dans un repeater
NB : ici, j'ai utilisé une astuce pour récupérer l'id de l'item du repeater. En effet, dans le OnLoad il vaut null, je force la génération du ClientId pour pouvoir récupérer l'ID.

Créé le 10 mars 2008  par nico-pyright(c)

Soit une DropDownList:

 
Sélectionnez
<asp:DropDownList id="ddl" runat="server"> 
	<asp:ListItem Value="1">Choix 1</asp:ListItem> 
	<asp:ListItem Value="2">Choix 2</asp:ListItem> 
	<asp:ListItem Value="3">Choix 3</asp:ListItem> 
</asp:DropDownList>

Ensuite, dans le code:

 
Sélectionnez
ddl.Attributes.Add("onchange","this.disabled=true;" )

ou directement dans le .aspx:

 
Sélectionnez
<asp:DropDownList id="ddl" runat="server" onchange="this.disabled=true;"> 
	<asp:ListItem Value="1">Choix 1</asp:ListItem> 
	<asp:ListItem Value="2">Choix 2</asp:ListItem> 
	<asp:ListItem Value="3">Choix 3</asp:ListItem> 
</asp:DropDownList>
Créé le 4 septembre 2006  par Didier Danse

Soit une liste déroulante déclarée en html de telle manière (ou une DropDownList qui est l'équivalent en asp.NET):

 
Sélectionnez
<SELECT id="Couleur" runat="server" name="Couleur" ></SELECT>

Cette liste a pour but d'afficher la liste des couleurs possibles avec la couleur en fond de chaque item.
Dans le code de traitement, il suffit alors d'inclure

 
Sélectionnez
Imports System.Reflection

et enfin d'ajouter les différents Items à la liste.

 
Sélectionnez
For Each col As FieldInfo In GetType(KnownColor).GetFields
	If col.FieldType = GetType(KnownColor) Then
		Couleur.Items.Add(New ListItem(col.Name, col.Name))
	End If
Next
Dim i As Integer = 0
While i < Couleur.Items.Count
	Couleur.Items(i).Attributes.Add("style", "background-color:" + Couleur.Items(i).Text)
	System.Math.Min(System.Threading.Interlocked.Increment(i),i-1)
End While

On peut imaginer d'autres utilisations telles mettre en rouge la liste des factures non payées et en vert celles qui sont payées dans une application de gestion de factures.

Créé le 19 juin 2005  par Didier Danse

On met la propriété AutoPostBack à true. Le principe est d'empecher la publication du postback en modifiant le javascript de l'attribut onchange pour qu'il renvoit false lorsque les conditions ne sont pas respectées.

 
Sélectionnez
myDropDownList.AutoPostBack = true
myDropDownList.Attributes["onchange"] =  "if(" + myDropDownList.ClientID + ".selectedIndex != " + myDropDownList.ClientID + ".length-1) return false; else"

le code est completé lors de la génération de la page. Dans le code html généré, __doPostBack(...) sera automatiquement rajouté après le else (parce qu'on à mis le AutoPostBack = true).
Dans cet exemple, on envoit le formulaire uniquement lorsque c'est le dernier élément qui est sélectionné.

Créé le 13 octobre 2008  par sam_XIII (Samuel Beauvois)

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2007 Dotnet Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.