2011-01-13 14 views
6

Ich habe eine ListBox, die ich ListItems in einem Codebehind hinzufügen. Das Problem, das ich habe, ist, dass die ListBox die ausgewählten Elemente nicht sieht. Ich habe die ListBox dynamisch gefüllt, abhängig davon, was der Benutzer aus einer DropDownList auswählt, also hat die DropDownList AutoPostBack auf true gesetzt. Ich denke, das verursacht irgendwie das Problem.ListBox erhält keine ausgewählten Objekte

Meine SelectedIndexChanged Methode, die immer dann verwendet wird, wenn ein Element in der DropDownList ausgewählt ist, ruft eine Methode namens PopulateListBox auf. Hier ist, was diese Methoden wie folgt aussieht:

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

Für das, was es wert ist, hier ist die Dropdownlist und List-Box:

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

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

Was ich versuche zu tun ist, eine Liste von Strings hinzufügen (Strings wobei die ausgewählten Elemente) als Sitzungsvariable beim Klicken auf eine Senden-Schaltfläche. Die Schaltfläche leitet zu einer neuen Seite um, nachdem die Liste der Sitzung hinzugefügt wurde. Im Debugger ist die Liste der Strings an dem Punkt leer, an dem ich sie zur Sitzung hinzufüge.

listbox.GetSelectedIndices() gibt nichts zurück.

aktualisieren

kann ich die ausgewählten Elemente zugreifen, wenn ich in der Dropdown keine Änderung vornehmen. Die ListBox wird anfänglich beim Laden der Seite gefüllt, und wenn ich eine Auswahl mache, werden sie erkannt. Wenn ich etwas aus der DropDownList wähle und die ListBox neu auffüllt, werden die Auswahlen nicht erkannt.

Meine Page_Load Methode macht nur zwei Dinge. Er initialisiert meine Api Variable und ruft PopulateDropDown, die wie folgt aussieht:

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

Aber wann können Sie ausgewählte Elemente in der Listbox nicht sehen? Beim Ändern der Auswahl in der Dropdown-Liste? Oder haben Sie eine andere Kontrolle, die Postback durchführt? – dzendras

+0

@dzendras: Ich habe den Beitrag unten in Bezug auf das aktualisiert. –

+0

Wann greifen Sie auf die Listbox zu? PageLoad? Überprüfen Sie, ob der Ort, an dem Sie darauf zugreifen, gemäß dem ASP.NET-Seitenlebenszyklus in Ordnung ist (In frühen Stadien der Verarbeitung von Anforderungssteuerelementen sind die Eigenschaften nicht festgelegt). Überprüfen Sie auch, ob Sie die Listbox nicht früher im Seitenlebenszyklus löschen. – dzendras

Antwort

13

Das Problem ist, dass Sie PopulateDropDown() auf jeder einzelnen Page_Load(), rufen die PopulateListBox() aufruft, die das Listenfeld löscht und füllt ihn wieder auf sie. Durch Löschen der Listbox löschen Sie die Auswahl.

Sie müssen Ihren Anruf zu PopulateDropDown() im Page_Load() mit dem folgenden Code ersetzen. Das Problem, das Sie nicht erkennen, ist, dass die Seite bei jedem Postback geladen wird - und dass die Seitenladung im Seitenlebenszyklus vor dem Ereignis auftritt. Wenn Sie also ein Dropdown-Element auswählen, führen Sie zuerst das Ereignis Page_Load() aus (wodurch die Methode LoadListBox indirekt ausgeführt wird und die Auswahl gelöscht wird). Der folgende Code füllt die Dropdownliste beim erstmaligen Laden der Seite nur. Halten Sie es das gleiche bei allen anderen die Last Drop-Down-Methode verwenden:

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

Die IsPostBack einen boolean zurück, der angibt, ob der Server-Seite Code ausgeführt wird, da die Seite zum ersten Mal geladen wird („false“) oder als ein Post zurück ("wahr").

Wie bereits an anderer Stelle erwähnt, muss ein Listenfeld mit einem Potenzial für mehrere ausgewählte Werte anders behandelt werden als eines mit Potenzial für eine einzelne Auswahl.Verweisen Sie nicht listbox.SelectedItem, sondern:

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

Ah, danke Justin. Die DropDownList ruft nur ein Postback auf, weil AutoPostBack dafür auf true gesetzt ist, richtig? Ich werde morgen Ihre Lösung ausprobieren und Ihnen Bericht erstatten. –

+0

Ja, aber wenn Sie AutoPostBack auf false setzen, wird der C# -Code nicht ausgeführt, wenn Sie Indizes ändern, was bedeutet, dass die Listbox nicht erneut gefüllt wird. –

1

Ich habe auch festgestellt, dass, wenn Sie die List-Box-Server-Seite zu deaktivieren, dann Client-Seite Code verwenden, um das Listenfeld mit Code wie die folgenden aktivieren, dann können Sie nicht bekommen die ausgewählten Elemente Server-Seite.

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

Die Lösung ist einfach sicherzustellen, dass es aktiviert ist Server-Seite (die Standardeinstellung), deaktivieren Sie es dann (siehe Schlag) oder ermöglicht es (siehe oben) clientseitigen Code.

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