Trying to make the entire Row red if object is checked out / checked in. here is my current code, I know this might be simple but I'm a noob.
<ItemTemplate>
<tr id="trId" runat="server">
<td style="text-align: left;">
<%#Eval("Name")%>
</td>
<td style="text-align: left;">
<asp:Label ID="lblDescription" runat="server" Text='<%#Eval("Description")%>'></asp:Label>
</td>
<td style="text-align: left; display: none;">
<asp:CheckBox ID="chkStatus" runat="server" Checked='<%#Eval("CheckedOut")%>' />
</td>
<td style="text-align: left;">
<asp:Label ID="lblStatus" runat="server" Text='<%#Eval("Status")%>'></asp:Label>
</td>
<td style="text-align: left;">
<asp:Label ID="lblLocation" runat="server" Text='<%#Eval("Location")%>'></asp:Label>
</td>
<td style="text-align: left;">
<asp:Button ID="btnChangeStatus" Postback="false" runat="server" Width="150"
CommandArgument='<%#Eval("CatId") & "^" & Eval("CheckedOut")%>' OnClick="ChangeStatus" CssClass="btn btn-default" Font-Bold="True" />
</td>
<td style="text-align: left;">
<asp:Button ID="btnEdit" PostBack="false" runat="server" Text="Edit" CssClass="btn btn-default" Width="150"
CommandArgument='<%#Eval("CatId")%>' OnClick="Edit" />
</td>
</tr>
</ItemTemplate>
Protected Sub CheckPermissions(sender As Object, e As RepeaterItemEventArgs) Handles rep_Data.ItemDataBound
If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim chkStatus As CheckBox = CType(e.Item.FindControl("chkStatus"), CheckBox)
Dim btnChangeStatus As Button = CType(e.Item.FindControl("btnChangeStatus"), Button)
Dim lblStatus As Label = CType(e.Item.FindControl("lblStatus"), Label)
If chkStatus.Checked = False Then
btnChangeStatus.Text = "Check Out"
Else
btnChangeStatus.Text = "Check In"
lblStatus.ForeColor = Drawing.Color.Red
End If
CodePudding user response:
Ok, would have been nice if you had noted if this is a GridView or ListView.
However, looking at markup - looks like a ListView - and they are a great control to use - my favorite. While a GridView is often less markup, when you REALLY want to layout more complex grids, then ListView starts to win (over all, even often less markup overall - and MUCH more formatting/style options exist.
As a general rule, the most opportune choice for row formatting (or even a single control) for a given column? use the row data bound event.
You also don't share where/when/how that sample code you have is to run?
but, for the time being, we will assume that you going to feed that listview some data.
Also you do have two buttons - but you set postback = false for the buttons? (Why??). And in fact there is NO PostBack="False" for buttons anyway. So, remove that.
We can wire up the buttons in a bit - but first step is to get our conditional formatting, and that "text" of "check in" and "check out" working for the existing data in the first place. Then, we can deal with the two button clicks.
so, we use row data bound event. There are SEVERAL reasons for this, but during that "event", you can not only get the whole list view row BUT ALSO get at columns NOT in the list view DURING the row bound event!!!. So I might want to highlight on some value, or flag that is NOT even in the ListView display - but WAS part of the data source. This means you often don't have to include some hidden column values - so keep this all important tip in mind.
so, say we have this listview:
<div style="width:50%">
<asp:ListView ID="ListView1" 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="CityLabel" runat="server" Text='<%# Eval("City") %>' />
</td>
<td>
<asp:Label ID="Desciption" runat="server" Text='<%# Eval("Description") %>' />
</td>
<td>
<asp:CheckBox ID="ActiveCheckBox" runat="server" Checked='<%# Eval("Active") %>' />
</td>
<td>
<asp:label ID="ActiveText" runat="server" />
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" border="0" class="table">
<tr runat="server" style="">
<th runat="server">FirstName</th>
<th runat="server">LastName</th>
<th runat="server">City</th>
<th runat="server">Descripiton</th>
<th runat="server">Active</th>
<th runat="server">Active Text</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
Not too much markup. We can then fill the LV with this code:
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()
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String = "SELECT TOP 10 * from tblHotels WHERE Description is not null ORDER BY HotelName"
Using cmdSQL = New SqlCommand(strSQL, conn)
conn.Open()
Dim rstData = New DataTable()
rstData.Load(cmdSQL.ExecuteReader)
ListView1.DataSource = rstData
ListView1.DataBind()
End Using
End Using
End Sub
And our output is now this:
Now, lets format the above that say non active rows are say red background.
And we ALSO will set the active text
(if active = true), then You can book!
(if active = false), the text = "don't use"
So, as noted, we use the row data bound event.
But we need to add a "id" to the row markup like this:
<ItemTemplate>
<tr id="onerow" runat="server">
<td>
<asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' />
</td>
so, we called it one row.
Now, in our data item bound event, we have this code:
Protected Sub ListView1_ItemDataBound(sender As Object, e As ListViewItemEventArgs) Handles ListView1.ItemDataBound
If e.Item.ItemType = ListViewItemType.DataItem Then
Dim ckBox As CheckBox = e.Item.FindControl("ActiveCheckBox")
Dim txtActive As Label = e.Item.FindControl("ActiveText")
Dim onerow As HtmlTableRow = e.Item.FindControl("onerow")
If ckBox.Checked = False Then
txtActive.Text = "Dont use"
' set whole row to red (light red
onerow.BgColor = "LightCoral"
Else
txtActive.Text = "Use Me"
' set whole row to red (light red
onerow.BgColor = "Lightskyblue"
End If
End If
End Sub
And now we have this:
Now the next part is those two button click events. We do and can and want some code for those two buttons.
So this one first:
<td style="text-align: left;">
<asp:Button ID="btnChangeStatus" runat="server" Width="150"
CommandArgument='<%#Eval("CatId") & "^" & Eval("CheckedOut")%>' OnClick="ChangeStatus" CssClass="btn btn-default" Font-Bold="True" />
Ok, I removed your PostBack=False.
And above - Change Status event? that does not look right.
We can't easy double click on the button "inside" of the listview to wire up a click event - but you CAN AND SHOULD do this from markup like this:
In the markup Type in OnClick=
when you hit =, you get this:
choose create new event. Looks like nothing occurred.
the markup will change to:
<asp:Button ID="btnChangeStatus" runat="server" Text="Button"
OnClick="btnChangeStatus_Click"
/>
So, now we can go to code behind, and we have our click event.
You can get the row click and work that row any way you want with this:
Protected Sub btnChangeStatus_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim lvRow As ListViewItem = btn.NamingContainer
' now our code is anything we want, say simular to item data bound event.
Dim ckBox As CheckBox = lvRow.FindControl("ActiveCheckBox")
Dim txtActive As Label = lvRow.FindControl("ActiveText")
Dim onerow As HtmlTableRow = lvRow.FindControl("onerow")
If ckBox.Checked = False Then
txtActive.Text = "Dont use"
' set whole row to red (light red
onerow.BgColor = "LightCoral"
Else
txtActive.Text = "Use Me"
' set whole row to red (light red
onerow.BgColor = "Lightskyblue"
End If
' -------- or get command arugments????
Dim str = btn.CommandArgument
End Sub
Or, your code would be say like this in the above event:
' -------- or get command arugments????
Dim btnChangeStatus As Button = sender
Dim lvRow As ListViewItem = btn.NamingContainer
Dim chkStatus As CheckBox = lvRow.FindControl("chkStatus")
Dim lblStatus As Label = lvRow.FindControl("lblStatus")
If chkStatus.Checked = False Then
btnChangeStatus.Text = "Check Out"
Else
btnChangeStatus.Text = "Check In"
lblStatus.ForeColor = Drawing.Color.Red
End If
So, we get the button, get the container (the list view row), and then code away as per above. so above is "smaple", but you can have any code you want for that single row button click as per above.