Technology Lover
Technology Lover

Reputation: 239

How to disable this LinkButton inside GridView control?

I am developing a registration system that lists events and the users will be able to register in these events. Each event has a specific number of seats. The problem that I am facing now is even when the number of registration reaches the number of seats, the event is still avaiable and I cannot stop the booking process by disabling booking button.

For your information, I have the following database design:

Event Table: ID, Title, NumberOfSeats
BookingDetails Table: BookingID, EventID, Username
User Table: Username, Name

The events will be listed in a GridView control and there is LinkButton inside the GridView for booking in the event. I am using a ModalPopUp Extender control and this is why I am using a LinkButton as shown in the ASP.NET code below. In the code-behind, inside the GrivView_RowDataBound, I compared between the number of seats and the number of bookings for each event. If the number of bookings greater than or equal to the number of seats. Booking button should be disabled. I wrote the code but I don't know why it is not working with me and why I am getting the following error: Unable to cast object of type 'System.Web.UI.WebControls.GridView' to type 'System.Web.UI.WebControls.LinkButton'.

ASP.NET code:

<asp:GridView ID="ListOfAvailableEvents_GrivView" runat="server" AutoGenerateColumns="False"
                    DataKeyNames="ID" CellPadding="4" DataSourceID="SqlDataSource1" ForeColor="#333333"
                    GridLines="None" AllowPaging="True" PageSize="10" 
                    onrowdatabound="ListOfAvailableEvents_GrivView_RowDataBound">
                    <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
                    <RowStyle BackColor="#F7F6F3" ForeColor="#333333" CssClass="generaltext" />
                    <Columns>
                        <asp:TemplateField HeaderText="">
                            <ItemTemplate>
                                <asp:LinkButton ID="lnkTitle" runat="server" CssClass="button" Text="Book &rarr;" OnClick="lnkTitle_Click"></asp:LinkButton>
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
                        <asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
                        <asp:BoundField DataField="Location" HeaderText="Location" SortExpression="Location" />
                        <asp:BoundField DataField="StartDateTime" HeaderText="Start Date & Time" SortExpression="StartDateTime" />
                        <asp:BoundField DataField="EndDateTime" HeaderText="End Date & Time" SortExpression="EndDateTime" />
                    </Columns>
                    <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
                    <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
                    <HeaderStyle Font-Bold="True" CssClass="complete" />
                    <EditRowStyle BackColor="#999999" />
                    <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
                    <EmptyDataTemplate><h2>No Events Available</h2></EmptyDataTemplate>
                </asp:GridView>

Code-Behind (C#) code:

protected void ListOfAvailableEvents_GrivView_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        int numberOfBookings = 0;
        int numberOfAvailableSeats = 0;

        string connString = "..........."
        string selectCommand = @"SELECT     COUNT(*) AS UserBookingsCount, dbo.Events.NumberOfSeats
                                    FROM         dbo.BookingDetails INNER JOIN
                                                          dbo.Events ON dbo.BookingDetails.EventID = dbo.Events.ID
                                    GROUP BY dbo.Events.NumberOfSeats";
        using (SqlConnection conn = new SqlConnection(connString))
        {
            //Open DB Connection
            conn.Open();
            using (SqlCommand cmd = new SqlCommand(selectCommand, conn))
            {
                SqlDataReader reader = cmd.ExecuteReader();
                if (reader != null)
                    if (reader.Read())
                    {
                        numberOfBookings = Int32.Parse(reader["UserBookingsCount"].ToString());
                        numberOfAvailableSeats = Int32.Parse(reader["NumberOfSeats"].ToString());
                    }
            }
            //Close the connection
            conn.Close();
        }

        if (numberOfBookings >= numberOfAvailableSeats)
        {
            LinkButton bookButton = (LinkButton)(sender);
            bookButton.Enabled = false;
        }
    }

So could you please tell me how to fix this problem?

UPDATE:

The GridView lists many different events. Let us take one of them. If event A has 3 available seats and the number of bookings reaches 3, the 'Book' button should be disabled only for this event not for all of them. So the button will be disabled for this event when the number of bookings reaches the number of available seats.

Upvotes: 2

Views: 7120

Answers (3)

Sky5005e
Sky5005e

Reputation: 79

Please use below code to hide the LinkButton, i.e. lnkTitle.

The code is as follows:

protected void ListOfAvailableEvents_GrivView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    int numberOfBookings = 0;
    int numberOfAvailableSeats = 0;

    string connString = "Data Source=appServer\\sqlexpress;Initial Catalog=EventRegMgnSysDB;Integrated Security=True;";
    string selectCommand = @"SELECT     COUNT(*) AS UserBookingsCount, dbo.Events.NumberOfSeats
                                FROM         dbo.BookingDetails INNER JOIN
                                                      dbo.Events ON dbo.BookingDetails.EventID = dbo.Events.ID
                                GROUP BY dbo.Events.NumberOfSeats";
    using (SqlConnection conn = new SqlConnection(connString))
    {
        //Open DB Connection
        conn.Open();
        using (SqlCommand cmd = new SqlCommand(selectCommand, conn))
        {
            SqlDataReader reader = cmd.ExecuteReader();
            if (reader != null)
                if (reader.Read())
                {
                    numberOfBookings = Int32.Parse(reader["UserBookingsCount"].ToString());
                    numberOfAvailableSeats = Int32.Parse(reader["NumberOfSeats"].ToString());
                }
        }
        //Close the connection
        conn.Close();
    }
 if (e.Row.RowType == DataControlRowType.DataRow)
    {

        LinkButton lnkTitle = (LinkButton )e.Row.FindControl("lnkTitle");


         if (numberOfBookings >= numberOfAvailableSeats)
        {

            lnkTitle.Visible = false;
        }
        else
        {

            lnkTitle.Visible = true;
        }

    }
}

Please mark it if you will get your answer.

Upvotes: 1

Dev
Dev

Reputation: 6710

Try :

LinkButtton lbtn = new LinkButtton();
lbtn = (LinkButton)e.Row.FindControl("ButtonId"); 

Then use lbtn for further operations.

Thanks

Upvotes: 1

scartag
scartag

Reputation: 17680

The RowDataBound event is for the GridView so the sender parameter cannot be cast into a LinkButton.

Modify you code to include the following.

if(numberOfBookings >= numberOfAvailableSeats)
{

if (e.Row.Cells[0].HasControls())
        {
            var button = e.Row.Cells[0].Controls[1] as LinkButton;

            button.Enabled = false;

        }
}

I worry about how you are approaching this though.

The RowDataBound event triggers for EVERY row in the datasource it is bound to and you are doing a database query each time.

You could try to include numberOfBookings and numberOfAvailableSeats in your initial query and those will be available to you and you can check them each time (per row) without having to go to the database each time.

Upvotes: 0

Related Questions