Search code examples
asp.netvb.netgridviewrow

Changing row colour with an onClick in VB


how do I change the background colour of a row when I click on some text within it? I am simply wanting to highlight that row. I've added an onclick event but no idea how to light up the row. Here's what I have..

        <asp:GridView ID="gdvOrders" width="100%" runat="server" style="font-size:1.8em" ShowHeaderWhenEmpty="True" EmptyDataText="No orders" AllowPaging="True" AutoGenerateColumns="False" CssClass="mGrid" DataKeyNames="orderID" DataSourceID="DSOrders" PageSize="20" AllowSorting="True">
            <AlternatingRowStyle CssClass="alt" />
            <Columns>  

                <asp:TemplateField HeaderText="Order">
                    <ItemTemplate>
                        <asp:LinkButton ID="LnkBtn1" onclick="LnkBtn1_Click" runat="server" Text='<%# Eval("ordertext") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="price" HeaderText="Price" />
.........

VB

Protected Sub LnkBtn1_Click(sender As Object, e As System.EventArgs)

     Dim LnkBtn1 As LinkButton = CType(sender, LinkButton)

End Sub

Solution

  • Ok, let's write some code to highlight the row using vb. As pointed out, this is a kind of using a "mountain" to drop on a small ant of a problem. (much better to do this client side).

    However, let's do this with server-side code, since there are MANY things to be learned from this example. (such as picking up the current row in a GridView based on button click).

    So, while 100% client-side JavaScript is a great idea, it can often not be all that simple, since the previous row that is highlighted now has to be un-highlighted!

    So, say this simple GridView with a button in the row.

            <asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False"
                DataKeyNames="ID" CssClass="table table-hover"
                Width="50%">
                <Columns>
                    <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
                    <asp:BoundField DataField="LastName" HeaderText="LastName" />
                    <asp:BoundField DataField="City" HeaderText="City" />
                    <asp:BoundField DataField="HotelName" HeaderText="Hotel" />
                    <asp:BoundField DataField="Description" HeaderText="Descriptioin" />
                    <asp:TemplateField HeaderText="Edit"
                        ItemStyle-HorizontalAlign="Center" ItemStyle-Width="130px">
                        <ItemTemplate>
                            <asp:Button ID="cmdEdit" runat="server" Text="Select"
                                OnClick="cmdEdit_Click"
                                />
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
    

    And code behind to load up this grid:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        If Not IsPostBack Then
            LoadData()
        End If
    
    End Sub
    
    Sub LoadData()
    
        GVHotels.DataSource = MyRst("SELECT * FROM tblhotelsA ORDER BY HotelName")
        GVHotels.DataBind()
    
    End Sub
    

    And also note in above, we have a standard button in the GridView

    And that button can have this code:

    Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
    
        Dim btn As Button = sender
        Dim gRow As GridViewRow = btn.NamingContainer
    
        gRow.BackColor = System.Drawing.Color.LightSkyBlue
    
        If ViewState("LastRow") IsNot Nothing Then
            ' we have to un-highligt the previous row
            Dim RowIX As Integer = ViewState("LastRow")
            Dim gRow2 As GridViewRow = GVHotels.Rows(RowIX)
            gRow2.BackColor = System.Drawing.Color.White
        End If
    
        ViewState("LastRow") = gRow.RowIndex
    
    End Sub
    

    So, note how when we highlight a row, we ALSO have to un-highlight the previous row.

    The effect now looks like this:

    enter image description here

    However, perhaps it of greater ease to just let the cursor "hover" over the row. Note how the above grid already has a "hover" built int.

    That code free row hover effect was done with this setting of the GridView:

    CssClass="table table-hover"
    

    So, in fact, table, and table-hover are bootstrap classes, and assuming that you have bootstrap installed (you VERY likely do, since that is the default for templates), then perhaps just a cursor hover will suffice.

    As noted, note how the row button click picks up the CURRENT row clicked on by using naming container. This works for repeaters, GridView, ListView and more. This approach also means you don't have to use or care about specific GridView events such as command name. In fact, for such row clicks, I suggest you use the above naming container for such events.

    Edit: Allow a re-load and re-bind of Grid, keeping rows.

    So, to allow/keep the highlighted rows EVEN with a re-load?

    Then we need 2 new parts:

    First part, keep a list of the primary key values from the database.

    Second part, add to the re-bind routine code to highlight any existing row in our list of rows.

    So, code now becomes this:

    Dim MyIDList As New List(Of Integer)
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        If Not IsPostBack Then
            LoadData()      ' first time grid load
            ViewState("IDList") = MyIDList
        Else
            MyIDList = ViewState("IDList")
        End If
    
    End Sub
    
    Sub LoadData()
    
        GVHotels.DataSource = MyRst("SELECT * FROM tblhotelsA ORDER BY HotelName")
        GVHotels.DataBind()
    
    End Sub
    
    
    Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
    
        Dim btn As Button = sender
        Dim gRow As GridViewRow = btn.NamingContainer
    
        Dim PK As Integer = GVHotels.DataKeys(gRow.RowIndex)("ID")
    
        If MyIDList.Contains(PK) Then
            ' ROW WAS Highliged, remove from list and un-highlight
            MyIDList.Remove(PK)
            gRow.BackColor = System.Drawing.Color.White
        Else
            ' not in our list, add to light, and highlight row
            MyIDList.Add(PK)
            gRow.BackColor = System.Drawing.Color.LightSkyBlue
        End If
    
    End Sub
    
    Protected Sub GVHotels_RowDataBound(sender As Object, e As GridViewRowEventArgs)
    
        If e.Row.RowType = DataControlRowType.DataRow Then
    
            Dim PKID As Integer = GVHotels.DataKeys(e.Row.RowIndex)("ID")
            If MyIDList.Contains(PKID) Then
                e.Row.BackColor = System.Drawing.Color.LightSkyBlue
            End If
    
        End If
    
    
    End Sub
    
    Protected Sub Button1_Click(sender As Object, e As EventArgs)
    
        LoadData()
    
    End Sub
    

    So, the last button is to test our code, and it does a 100% re-load.

    The results are this:

    enter image description here