Radiobuttongroup in Listviews

Asp.Net Webforms

Der Blogartikel ergibt sich aus der Praxis. Beim Programmieren in Asp.Net bin ich auf ein größeres Problem gestoßen, dass auch nicht (wirklich) irgendwo im Internet gelöst wurde. Das Problem Radiobuttons in Listviews verhalten sich eigentlich wie Checkboxen und lassen sich nicht gruppieren. Bei den vielen Ansätzen die ich versucht habe, löste ein Workaround das nächste Problem aus. 

Hier in dem Blog zeige ich euch die in meinen Fall beste Lösung.

 

1. Problem

<ItemTemplate>

<tr>

<td>

<%#Eval("Title") %>

<%#Eval("Speaker") %>

</td>

<td>

    <asp:RadioButton runat="server" GroupName= ' "Groupname" + <%#Eval("InputBoxName")%>' />

</td>

</tr>

</ItemTemplate>

 

Der Radiobutton wird vom Server gerendert und das GroupNamenattribut wird nur angehängt statt zugewiesen. Somit ist der Name jedes einzelnen Radiobuttons einzigartig und unabhängig von einer Gruppe.

<input type="radio" name="…$outerListview$ctrl1$innerListview$ctrl0$name = 'Grpname1'"/>

<input type="radio" name="…$outerListview$ctrl1$innerListview$ctrl1$name = 'Grpname1'"/>

 

Workaround

Es gibt viele Workarounds, in JavaScript als auch C#, die den Gruppennamen manuell austauschen. Doch mit dem Löschen/Verändern des Namens geht auch der Status des Inputs bei den Postbacks verloren, somit weiß man nicht mehr welche Radiobuttons „true“ waren.
Da wir noch die Eingabe des Users auswerten wollen, stellen wir mit jQuery (JavaScript Framework) nur das Verhalten nach.

 

Mein ganzer Quellcode wird in document.ready gepackt um sicherzugehen, dass alle Elemente fertig geladen wurden.
Normalerweise werden beim Wählen eines Radios in einer Gruppe die Restlichen deaktiviert. Sozusagen das Klicken auf den Radiobutton löst das Event aus.

Für den nächsten Schritt betrachten wir den Namen der Inputbox nochmal genauer…
name="…$outerListview$ctrl1$innerListview$ctrl1$name = 'Grpname1'"

Von dem String brauchen wir alle Zeichen ab der Stelle $name = '. Das letzte Hochkomma fällt auch noch weg. Was übrig bleibt ist der eigentliche Gruppenname.

 

$(document).ready(function () {

   $("input[type='radio']").change(function () {

 

var fullName = $(this).attr("name");               // Der Name als String
var groupName = "$name = '", input = $(this);

//herausfiltern des Namens
var name = fullName.substr(fullName.indexOf(groupName)+ groupName.length, fullName.length-1));

 
$(
" input[name*=" + name + "]").each(function () {
       /*Jedes Gruppenmitglied, dass nicht die Funktion
       aufgerufen hat wird zurück gesetzt*/

if (input.attr("name") != $(this).attr("name")) {

$(this).removeAttr("checked");

}

});

   });

});

 

 

 

 

2. Problem

Auf die Radiobuttons selbst kann man nicht zugreifen, da sie keine Id besitzen. Selbst wenn man Ids mit einem Eval zuweisen würde, bei langen Listen wäre es ein zu großer Aufwand jeden einzelnen Anzusprechen. 

 

Workaround

Aus diesem Grund macht es Sinn sich dem gemeinsamen Elternelement zuzuwenden, denn (in diesem Beispiel die Listview) die Kinderelemente beinhaltet. Die Controles sind in einem Array organisiert und mit Hilfe des Indexes kann man auf die zugreifen

Wir laufen im Listview alle Itemtemplates durch und in dem Itemtemplates wiederum die einzelnen Controles.

 

for (int i = 0; i <= MyListview.Items.Count - 1; i++){

    for (int col = 0; col <= MyListview.Controls[i].Controls.Count - 1; col++)    {

        if (MyListview.Controls[i].Controls[col].GetType().Name == " RadioButton ")    {

            RadioButton chkTemp = (RadioButton)MyListview.Controls[i].Controls[col];
      
     // Speicher die Daten evtl in einer Datenbank

        }

    }

}

Es gibt die Möglichkeit Itemtemplates nach eigenen Kriterien anzusprechen. Die Klasse, dessen Objekte wiedergegeben werden, bestehen aus Properties. Aus dem Properties kann man den Datenschlüssel definieren und dann in der If-Abfrage verwenden.

<asp:ListView ID=" MyListview" runat="server" DataKeyNames="Id">

    <ItemTemplate>

  ...

    </ItemTemplate>

</asp:ListView>

So hat man zB bei Sätzen aus der Datenbank gleich die richtige Id.
DbModel.YourTable.Find(MyListview.DataKeys[i].Value);

Kommentare sind geschlossen