Click here to Skip to main content
14,877,073 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
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:

SQL
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'.

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.

**ASP.NET code:

ASP
<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 →" 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:

C#
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 (numberOfBookings >= numberOfAvailableSeats)
           {
               LinkButton bookButton = (LinkButton)(sender);
               bookButton.Enabled = false;
           }
       }


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

EDIT:

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.
Posted
Updated 11-Jan-13 20:48pm
v2

The RowDataBound event fires on the GridView itself.
As a result, the sender in the line of code ListOfAvailableEvents_GrivView_RowDataBound(object sender, GridViewRowEventArgs e) is a GridView and not a Link button.

When you try and typecast GridView into a button, you are going to get an error.

You could try locating the LinkButton from inside the row - for e.g. LinkButton lb1 = (LinkButton)e.Row.FindControl("lb1");
and then disable from here lb1.Enabled=false;.
   
v2
Comments
matrix388 26-Dec-12 2:19am
   
I tried it and it doesn't work. It gave me the following error: System.NullReferenceException: Object reference not set to an instance of an object.
First of all your approach to the problem is not feasible. You are checking the Database for every row on row databound event(suppose you have 100 rows on a page). You can pass a flag that booking is available or not from your query itself for all the records that binds the gridview. In this way you can store it in a invisible textbox, label or literal. Then on rowdatabound event you can check for these flags and accordingly enable/disable the link button. Anyway, Your code may also work. You will have to make following changes:


1)
C#
if (numberOfBookings >= numberOfAvailableSeats)
{
LinkButton bookButton = (LinkButton)(e.Row.FindControl("lnkTitle"));
bookButton.Enabled = false;
}


2)To avoid the null reference error in rowdatabound event first check the row type, then write the code because by default the event will also check for header rows and it's there where it is not finding any link button.For that you can check as:

C#
if(e.Row.RowType == DataControlRowType.DataRow)
{
//Your code here
}
   
Comments
matrix388 12-Jan-13 2:46am
   
Still doesn't work. To elaborate more on this issue, 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.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900