2011-01-13 2 views
6

J'ai un ListBox auquel j'ajoute ListItems dans un codebehind. Le problème que j'ai est le ListBox ne voit pas les éléments sélectionnés. J'ai le ListBox étant peuplé dynamiquement en fonction de ce que l'utilisateur sélectionne à partir d'un DropDownList, de sorte que le DropDownList a AutoPostBack défini sur true. Je pense que c'est en quelque sorte causant le problème.ListBox n'obtenant pas les éléments sélectionnés

Ma méthode SelectedIndexChanged, qui est utilisée chaque fois qu'un élément de DropDownList est sélectionné, appelle une méthode appelée PopulateListBox. Voici ce que ces méthodes ressemble:

protected void SelectedIndexChanged(object sender, EventArgs e) 
{ 
    string typeStr = type.SelectedItem.Text; 
    MyType = Api.GetType(typeStr); 
    PopulateListBox(); 
} 

private void PopulateListBox() 
{ 
    listbox.Items.Clear(); 
    foreach (PropertyInfo info in MyType.GetProperties()) 
     listbox.Items.Add(new ListItem(info.Name)); 
} 

Pour ce que ça vaut la peine, voici la DropDownList et ListBox:

<asp:DropDownList runat="server" ID="type" width="281px" OnSelectedIndexChanged="SelectedIndexChanged" AutoPostBack="true" /> 

<asp:ListBox runat="server" ID="listbox" width="281px" height="200px" selectionmode="Multiple" /> 

Ce que je suis en train de faire est d'ajouter une liste de chaînes (chaînes étant sélectionné éléments) en tant que variable de session en cliquant sur un bouton de soumission. Le bouton redirige vers une nouvelle page après que la liste a été ajoutée à la session. En passant par le débogueur, la liste des chaînes est vide au point où je l'ajoute à la session.

listbox.GetSelectedIndices() ne renvoie rien.

Mise à jour

Je peux accéder aux éléments sélectionnés si je ne fais pas un changement dans la DropDownList. Le ListBox est initialement rempli sur le chargement de la page, et si je fais des sélections, ils sont reconnus. Si je sélectionne quelque chose dans DropDownList et que la ListBox est repeuplée, les sélections ne sont pas reconnues. La méthode Page_Load ne fait que deux choses. Initialisées ma variable Api et appelle PopulateDropDown, qui ressemble à ceci:

private void PopulateDropDown() 
{ 
    foreach (Type t in Api.GetAllTypes()) 
     type.Items.Add(new ListItem(t.Name)); 
    string typeStr = type.Items[0].Text; 
    Type = Api.GetType(typeStr); 
    PopulateListBox(); 
} 
+0

Mais quand ne voyez-vous pas les éléments sélectionnés dans la liste? Lors de la modification de la sélection dans la liste déroulante? Ou vous avez un autre contrôle effectuant la publication? – dzendras

+0

@dzendras: J'ai mis à jour le post en bas à ce sujet. –

+0

Quand accédez-vous à la liste? PageLoad? Vérifiez si l'endroit où vous y accédez est correct selon le cycle de vie de la page ASP.NET (les premières étapes du traitement des commandes de demande n'ont pas leurs propriétés définies). Vérifiez également si vous n'effacez pas la zone de liste plus tôt dans le cycle de vie de la page. – dzendras

Répondre

13

Le problème est que vous appelez PopulateDropDown() sur chaque Page_Load(), qui appelle PopulateListBox(), qui efface la zone de liste et repeuple il. En effaçant la liste, vous effacez la sélection. Vous devez remplacer votre appel à PopulateDropDown() par le code Page_Load(). Le problème que vous ne réalisez pas est que la page est chargée à chaque publication - et que dans le cycle de vie de la page, le chargement de la page se produit avant l'événement. Donc, en sélectionnant un élément déroulant, vous devez d'abord exécuter l'événement Page_Load() (qui exécute indirectement la méthode LoadListBox, en effaçant la sélection). Le code suivant va remplir la liste déroulante la première fois que la page se charge seulement. Gardez-même partout où vous utilisez la méthode déroulante de charge:

protected void Page_Load(object sender, EventArgs e) 
{ 
    // Do your API code here unless you want it to occur only the first 
    // time the page loads, in which case put it in the IF statement below. 
    if (!IsPostBack) 
    { 
     PopulateDropDown(); 
    } 
} 

Le IsPostBack renvoie un booléen indiquant si le code côté serveur est en cours d'exécution, car le chargement pour la première fois (« faux ») ou un retour ("vrai"). Comme je l'ai dit ailleurs, gardez à l'esprit qu'une liste de sélection avec un potentiel pour plusieurs valeurs sélectionnées doit être traitée différemment de celle avec un potentiel pour une sélection unique.Ne pas faire référence à listbox.SelectedItem, mais plutôt:

foreach (ListItem item in lbFullNames) 
{ 
    if (item.Selected) 
    { 
     // TODO: Whatever you are doing with a selected item. 
    } 
} 
+0

Ah, merci Justin. Le DropDownList appelle uniquement une publication, car AutoPostBack est défini sur true pour cela, n'est-ce pas? Je vais donner à votre solution un coup demain et faire un rapport. –

+0

Oui, mais si vous définissez AutoPostBack sur false, le code C# ne s'exécutera pas lorsque vous changez d'index, ce qui signifie que la zone de liste ne sera pas repeuplée. –

1

J'ai aussi trouvé que si vous désactivez le côté serveur ListBox, puis utilisez le code côté client pour activer la zone de liste à l'aide du code comme suit, alors vous ne pouvez obtenir le côté serveur des éléments sélectionnés.

$('.css-class-assigned-to-listbox').attr('disabled', ''); 

Le correctif est tout simplement pour vous assurer qu'il est activé côté serveur (par défaut), puis le désactiver (voir coup) ou l'activer (voir ci-dessus) en utilisant le code côté client.

$('.css-class-assigned-to-listbox').attr('disabled', 'disabled'); 
Questions connexes