Das Checklist Control fehlt bei ASP .NET in den Web Form Controls. Dabei benötigt man oft in einer Liste die Möglichkeit Einträge auszuwählen. Dies kann man natürlich mit der Listbox tun, dies aber mit grafischen und funktionellen Einschränkungen.
Die Lösung für diese Aufgabe ist es mit Hilfe des Repeaters und der Listbox dies selbst zu implementieren.
Innerhalb des Repeaters wird das Design im Itemtemplate festgelegt. Wenn Sie wollen, das jede zweite Zeile anderes dargestellt wird, benötigen Sie noch eine Sektion alternatingTemplate.
Im das Template können Sie dann die Daten anzeigen über den Databinder. Die Syntax ist ASP ähnlich (<%#..%>). Durch Zugriff auf den Databinder und die Auswertung über Eval wird aus dem DatenContainer ein Feld angezeigt. Um später den Datensatz wieder identifizeiren zu können wird in diesem Beispiel das Schlüsselfeld einem Label zugewiesen.
Zum Wählen eines Eintrages fehlt nur noch die Checkbox. Diese könnte man auch über die Eigenschaft Checked vorbelegen.
Der Code Schnippsel aus der ASPX Seite:
<asp:Repeater id="rptSessions" runat="server" EnableViewState="true"> <ItemTemplate> <asp:CheckBox id="Choice" runat="server" > </asp:CheckBox> <asp:Label id="SCode" runat="server"> <%# DataBinder.Eval(Container.DataItem, "SessionCode") %> </asp:Label> <b> <%# DataBinder.Eval(Container.DataItem, "Speaker") %> </b> <%# DataBinder.Eval(Container.DataItem, "description") %> <br> </ItemTemplate> </asp:Repeater> |
Am besten versteht man die Funktionsweise des Repeaters, wenn man sich einen Trace ansieht. Die Controls finden sich unterhalb des Repeaters als Collection wieder. Eine einfache Datenausgabe über <%#..%> wird als DataboundLiteralcontrol dargestellt. Einfacher HTML Code wird schon mal als Literalcontrol verpackt. Wichtig ist auch die Hirarchie. So werden die Daten des Labels als Child DataBoundLiteraltControl dargestellt.
rptSessions System.Web.UI.WebControls.Repeater 6288 40
rptSessions:_ctl0 System.Web.UI.WebControls.RepeaterItem 276 0
rptSessions:_ctl0:_ctl0 System.Web.UI.LiteralControl 11 0
rptSessions:_ctl0:Choice System.Web.UI.WebControls.CheckBox 87 0
rptSessions:_ctl0:_ctl1 System.Web.UI.LiteralControl 11 0
rptSessions:_ctl0:SCode System.Web.UI.WebControls.Label 52 0
rptSessions:_ctl0:_ctl2 System.Web.UI.DataBoundLiteralControl 10 20
rptSessions:_ctl0:_ctl3 System.Web.UI.DataBoundLiteralControl 115 60
Das Auswerten der gewählten Einträge wird über einen Button (Speichern) und dessen Eventhandler durchgeführt.
Der Code muss durch die Controls Collection durchiterieren. (Auf Deutsch: alle Elemente der ersten Ebene vom Repeater müssen bearbeitet werden). Innerhalb dieser Liste gibts wieder eine eigene Liste die über den Index angesprochen werden kann. Hir wird die Funktion FindControl verwendet um die Checkbox zu finden. Dies ist von Vorteil, wenn später eine Designer die Reihenfolge ändert, dann funktioniert Ihr Code noch.
Etwas komplexer ist es, die Daten des Labels zu finden. Dazu müssen Sie erst das Label über Findcontrol finden und dann das erste Control unterhalb des Labels in ein DataBoundLiteralControl mit dem Befehl CType Casten. Auf den ersten Blick etwas ungewöhnlich, wenn man sich aber daran gewöhnt hat wird man es lieben.
So und nun der Code:
...... Dim i As Integer For i = 0 To rptSessions.Items.Count - 1 Dim CurrentCheckBox As CheckBox = rptSessions.Items(i).FindControl("Choice") Dim lblCode As DataBoundLiteralControl = CType((rptSessions.Items(i).FindControl("SCode")), Label).Controls(0) Trace.Write("Labeltext", lblCode.Text) If CurrentCheckBox.Checked Then sql = "insert into konf_sel_sessions (sessioncode,ansprech_id) values ('" & lblCode.Text.Trim & "'," & Session("anid") & ")" Dim cmd As New SqlCommand(sql, mycon) Try cmd.ExecuteNonQuery() Catch End Try Else sql = "delete from konf_sel_sessions where sessioncode='" & lblCode.Text & "' and ansprech_id=" & Session("anid") Dim cmd As New SqlCommand(sql, mycon) Try cmd.ExecuteNonQuery() Catch End Try End If Next |
Der Rest des Codes ist nur der Vollständigkeit implementiert. Etwas schmutzig wird bei gewählten Eintrag ein Insert in die Datenbank durchgeführt. Bei unselektierten Eintrag wird ein Delete abgesendet. Weil hier keiner prüft und dies fehlschlagen könnte hilft ein Try Catch ein On Error Resume zu simulieren.
And it Works!