I have a list view that has a column of a radio button. I would like to only select one radio button at a time and be able to determine which row it has selected. I don't have a code on codebehind since I haven't figure out this yet. Below is my designer code:
asp:listview runat="server" ID="lsvPermits"
ItemPlaceholderID="itemApplication" DataKeyNames="PERMIT_TYPE_ID" style="width:100%">
<LayoutTemplate>
<table class="ListView_Style" cellspacing="0" border="1" style="border-collapse:collapse">
<tr class="ListView_Style ListView_HeaderStyle" >
<th align="center" scope="col" style="width: 10%;">
<asp:Label runat="server" ID="lblHeaderPurchase" Suffix="?"
Text="[Purchase?]"></asp:Label>
</th>
<th align="center" scope="col" style="width: 10%;">
<asp:Label runat="server" ID="lblHeaderPERMIT_TYPE_DESC"
Text="[PERMIT TYPE DESCRIPTION]" >
</asp:Label>
</th>
<asp:PlaceHolder ID="itemApplication" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr runat="server" id="trItem" >
<td valign="middle" style="white-space: nowrap; text-align:center;">
<Asp:RadioButton runat="server" ID="rbtnPermit" />
<td valign="middle" style="white-space: nowrap; text-align:center;">
<%# CheckNull(Eval("PERMIT_TYPE_DESC"))%>
</td>
<td valign="middle" style="white-space: nowrap; text-align:center;">
<%# CheckNull(Eval("PERMIT_TYPE_ID"))%>'
</td>
</td>
</tr>
<tr runat="server" ID="trMatchRow" >
</tr>
</ItemTemplate>
<EmptyDataTemplate>
<table class="ListView_Style" cellspacing="0" align="left" rules="all" border="1"
style="width: 100%; border-collapse: collapse;">
<tr >
<th align="center" scope="col" style="width: 10%;">
<asp:Label runat="server" ID="lblHeaderPurchase" Suffix="?"
Text="[Purchase?]"></asp:Label>
</th>
<th align="center" scope="col" style="width: 10%;">
<asp:Label runat="server" ID="lblHeaderPERMIT_TYPE_DESC"
Text="[PERMIT TYPE DESCRIPTION]" >
</asp:Label>
</th>
</tr>
<tr id="MatchRow0">
<td style= "text-align:center;" colspan="8" class="hideBorder">
<asp:Label runat="server" ID="lblNoRecords"
Text="[There are no records to display]" >
</asp:Label>
</td>
</tr>
</table>
</EmptyDataTemplate>
</asp:listview>
So the Radio button looks to be un-bound. (that's ok).
Say this sample markup, and we want to select one of the rows.
<asp:ListView ID="LVHotels" runat="server" DataKeyNames="ID" >
<ItemTemplate>
<tr style="">
<td><asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' /></td>
<td><asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' /></td>
<td><asp:Label ID="HotelName" runat="server" Text='<%# Eval("HotelName") %>' /></td>
<td><asp:Label ID="CityLabel" runat="server" Text='<%# Eval("City") %>' /></td>
<td><asp:Label ID="DescriptionLabel" runat="server" Text='<%# Eval("Description") %>' /></td>
<td style="text-align:center;vertical-align:middle">
<asp:RadioButton ID="rbActive" runat="server"
AutoPostBack="true"
OnCheckedChanged="rbActive_CheckedChanged"
/>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server"
class="table table-bordered table-hover" style="width:50%">
<tr runat="server" style="">
<th runat="server">FirstName</th>
<th runat="server">LastName</th>
<th runat="server" style="width: 200px">HotelName</th>
<th runat="server">City</th>
<th runat="server">Description</th>
<th runat="server">Active</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
And our code to load above is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid
End If
End Sub
Sub LoadGrid()
LVHotels.DataSource =
MyRst("SELECT * FROM tblhotelsA ORDER BY HotelName")
LVHotels.DataBind()
End Sub
And the result is now this:
Now let's deal with the radio button.
We need a auto postback, and also, since we can't double click on, or bring up the property sheet for the rb, we have to add the "event" by typing in the markup.
You can get vs to "create" the event stub (code behind) by typing in the event name, then "=", and NOTE VERY closely, vs should pop a context dialog.
This way:
Note VERY closely when we hit "=", then that create new event comes up, we click on that, and now we created the event stub in code behind.
Our rb button looks like this:
<asp:RadioButton ID="rbActive" runat="server"
AutoPostBack="true"
OnCheckedChanged="rbActive_CheckedChanged"
/>
Now all we have to do is add the code stub to code behind for that rb change event. Turns out you can NOT trigger the rb event if it is already clicked. This is good, since then it means our code behind stub ONLY triggers when the button is "assumed" to become true (checked).
All we do is un-check all the buttons (don't event care if we just un-checked our current button, since THEN we can just shove it back to correct value!!!).
This code:
Protected Sub rbActive_CheckedChanged(sender As Object, e As EventArgs)
' uncheck all rows first
Dim Radiobut As RadioButton
For Each lvRow As ListViewItem In LVHotels.Items
Radiobut = lvRow.FindControl("rbActive")
Radiobut.Checked = False
Next
Radiobut = sender
Radiobut.Checked = True ' this THIS button - since we un-checked them all
End Sub
And the result is now this:
Let's for "testing" just drop in a button and text box. We will click on the button, and show in text box the row user selected.
This markup below the list view:
<asp:Button ID="Button1" runat="server" Text="Show selected row" CssClass="btn"
OnClick="Button1_Click" />
<asp:TextBox ID="TextBox1" runat="server" style="margin-left:25px" Width="380px">
</asp:TextBox>
And now this code:
Protected Sub Button1_Click(sender As Object, e As EventArgs)
' get selected row
Dim sAnswer As String
Dim Radiobut As RadioButton
For Each lvRow As ListViewItem In LVHotels.Items
Radiobut = lvRow.FindControl("rbActive")
If Radiobut.Checked Then
Dim PK As Integer = LVHotels.DataKeys(lvRow.DisplayIndex).Item("ID")
Dim sHotel As Label = lvRow.FindControl("HotelName")
sAnswer = $"Row click = {lvRow.DisplayIndex}, Database pk = {PK}, Hotel = {sHotel.Text}"
Exit For
End If
Next
TextBox1.Text = sAnswer
End Sub
And now this:
As a FYI?
One "fast" becomes tired of typing SQL query and connection code over and over. So in above, I used a helper routine that simple takes some SQL and returns a .net data table.
The "MyRst" code used in above was this:
Public Function MyRst(strSQL As String) As DataTable
dim strCon as string = My.Settings.TEST4
Dim rstData As New DataTable
Using conn As New SqlConnection(strCon)
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function