Reputation: 239
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 →" 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
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
Reputation: 6710
Try :
LinkButtton lbtn = new LinkButtton();
lbtn = (LinkButton)e.Row.FindControl("ButtonId");
Then use lbtn
for further operations.
Thanks
Upvotes: 1
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