Loop through checkboxes in listview control to Update Database - c#

Below is my ASP.net code with my Listview Control with a checkbox absentCheckBox
<asp:ListView ID="student_list" runat="server" DataSourceID="view_students">
<ItemTemplate>
<tr style="">
<td>
<asp:Label Text='<%# Eval("assignment_id") %>' runat="server" ID="assignment_idLabel" />
</td>
<td>
<asp:Label Text='<%# Eval("user_id") %>' runat="server" ID="user_idLabel" />
</td>
<td>
<asp:TextBox Text='<%# Eval("result_percentage") %>' runat="server" ID="result_percentageTextBox" />
</td>
<td>
<asp:CheckBox Checked='<%# Eval("absent") %>' runat="server" ID="absentCheckBox" />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:Button ID="add_results" runat="server" Text="Update Results" OnClick="add_results_Click" CssClass="blue" />
Below is my C# code behind where I am trying to loop through the checkboxes in
protected void add_results_Click(object sender, EventArgs e)
{
foreach (ListViewItem item in student_list.Items)
{
int student_id = 0;
Label student_id_lbl = (Label)item.FindControl("user_idLabel");
student_id = Convert.ToInt32(student_id_lbl.Text);
int assignment_id = 0;
Label assignment_id_lbl = (Label)item.FindControl("assignment_idLabel");
assignment_id = Convert.ToInt32(assignment_id_lbl.Text);
int result = 0;
TextBox result_total_ddl = item.FindControl("result_percentageTextBox") as TextBox;
if (result_total_ddl != null)
{
if (Int32.TryParse(result_total_ddl.Text, out result))
{
}
else
{
}
}
bool absent = false;
CheckBox absent_chk = item.FindControl("absentCheckBox") as CheckBox;
absent = Convert.ToBoolean(absent_chk.Text);
if (result < 0 || result > 100)
{
feedback.Text = "Please enter an assignment total in between 0 - 100 you have entered : <b>" + result + "</b>.";
}
else
{
String connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection myConnection = new SqlConnection(connectionString);
myConnection.Open();
String query = "UPDATE assignments_vs_users SET result_percentage = #result_percentage, absent = #absent WHERE assignment_id = #assignment_id AND user_id = #student_id; ";
SqlCommand myCommand = new SqlCommand(query, myConnection);
myCommand.Parameters.AddWithValue("#result_percentage", result);
myCommand.Parameters.AddWithValue("#assignment_id", assignment_id);
myCommand.Parameters.AddWithValue("#student_id", student_id);
myCommand.Parameters.AddWithValue("#absent", absent);
myCommand.ExecuteNonQuery();
myConnection.Close();
}
}
}
How can I use absent within myCommand.Parameters.AddWithValue("#absent", absent); so it updates the database column for absent if the checkbox is ticked to true

Related

C#- Maintain State of Checkbox and textbox in gridview on page changing

I have a gridview having a textbox and a checkbox.when the checkbox is checked,a value will be populated into the textbox which a user may alter the value.
Here is the code for the gridview
<asp:GridView ID="gvPayment" runat ="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="Vertical" Width="100%" ShowFooter="true" CssClass="jumbSize1" OnRowDataBound="gvPayment_RowDataBound" AllowPaging="true" PageSize="5" OnPageIndexChanging="gvPayment_PageIndexChanging" >
<Columns>
<asp:TemplateField HeaderStyle-Width="5%">
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" CssClass="checkbox" OnCheckedChanged="chkSelect_CheckedChanged" AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="TRANSACTION DATE" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="SalesDate" runat="server" Text='<%#Eval("Date", "{0:dd/MM/yyyy}") %>' />
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="Submit" Text="Submit" runat="server" OnClick="Submit_Click" CssClass="btn btn-primary" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Sales Code" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="SalesCode" runat="server" Text='<%#Eval("SALES_CODE") %>' />
</ItemTemplate>
<FooterTemplate>
<div style="padding: 0 0 5px 0;">
<asp:Label Text="Page Totals" runat="server" align="right" />
</div>
<div>
<asp:Label Text="Grand Totals" runat="server" align="right" />
</div>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ACTUAL SALE" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="ActualSales" runat="server" Text='<%#Eval("ACTUAL", "{0:N2}") %>' />
</ItemTemplate>
<FooterTemplate>
<div style="padding: 0 0 5px 0;">
<asp:Label ID="PageActual" runat="server" align="right" />
</div>
<div>
<asp:Label ID="GrandActual" runat="server" align="right" />
</div>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ADVANCE" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="AdvPay" runat="server" Text='<%#Eval("ADVANCE", "{0:N2}") %>' />
</ItemTemplate>
<FooterTemplate>
<div style="padding: 0 0 5px 0;">
<asp:Label ID="PageAdvance" runat="server" align="left" />
</div>
<div>
<asp:Label ID="GrandAdvance" runat="server" align="left" />
</div>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="AMOUNT DUE" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="AmtDue" runat="server" Text='<%#Eval("DUE", "{0:N2}") %>' />
</ItemTemplate>
<FooterTemplate>
<div style="padding: 0 0 5px 0;">
<asp:Label ID="PageDue" runat="server" align="left" />
</div>
<div>
<asp:Label ID="GrandDue" runat="server" align="left" />
</div>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="AMOUNT PAID" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:TextBox ID="AmtPaid" runat="server" CssClass="form-control CapLock" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<AlternatingRowStyle BackColor="#4870BE" ForeColor="#FFFFFF" />
<FooterStyle BackColor="#76543c" ForeColor="#FFFFFF" Font-Bold="true" />
<HeaderStyle BackColor="#76543c" ForeColor="#FFFFFF" Font-Bold="true" />
<PagerSettings Mode="NextPrevious" NextPageText="Next &gt;&gt;" PreviousPageText="Prev &lt;&lt;" />
<PagerStyle BackColor="#76543c" ForeColor="#FFFFFF" HorizontalAlign="Center" />
<RowStyle BackColor="#EFF3FB" /></asp:Gridview>
Here is the code to bind gridview to data source and get the grand totals in viewstate
private void GetCustomer()
{
dt = new DataTable();
try
{
using (con = new SqlConnection(conString))
{
using (cmd = con.CreateCommand())
{
string query = #"dbo.sp_get_sales";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#ID", CustInfo.SelectedValue);
con.Open();
da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(dt);
//CALCULATE THE TOTAL AMOUNTS AND HOLD THE VALUE IN A "VIEWSTATE"
ViewState["TotalActual"] = null;
if (ViewState["TotalActual"] == null)
{
Decimal dActual = 0;
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
dActual += dt.Rows[i].Field<Decimal>("ACTUAL");
}
ViewState["TotalActual"] = dActual.ToString("N2");
}
ViewState["TotalAdvance"] = null;
if (ViewState["TotalAdvance"] == null)
{
Decimal dAdvance = 0;
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
dAdvance += dt.Rows[i].Field<Decimal>("ADVANCE");
}
ViewState["TotalAdvance"] = dAdvance.ToString("N2");
}
ViewState["TotalDue"] = null;
if (ViewState["TotalDue"] == null)
{
Decimal dDue = 0;
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
dDue += dt.Rows[i].Field<Decimal>("DUE");
}
ViewState["TotalDue"] = dDue.ToString("N2");
}
}
//BIND QUERY RESULT WITH THE GRIDVIEW
gvPayment.DataSource = dt;
gvPayment.DataBind();
}
}
catch (Exception ex)
{
ErrorMessage.Text = "An error occured: " + ex.Message;
}
finally
{
con.Close();
con.Dispose();
}
foreach (GridViewRow row in gvPayment.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
TextBox AmtPaid = (TextBox)row.FindControl("AmtPaid");
AmtPaid.Attributes.Add("readonly", "readonly");
}
}
}
Here is the code to enable and populate textbox on check changed event
protected void chkSelect_CheckedChanged(object sender, EventArgs e)
{
GridViewRow row = ((GridViewRow)((CheckBox)sender).NamingContainer);
int index = row.RowIndex;
CheckBox chkSelect = (CheckBox)gvPayment.Rows[index].FindControl("chkSelect");
TextBox AmtPaid = (TextBox)gvPayment.Rows[index].FindControl("AmtPaid");
Label AmtDue = (Label)gvPayment.Rows[index].FindControl("AmtDue");
if (chkSelect.Checked && chkSelect != null)
{
AmtPaid.Text = AmtDue.Text.Replace(",", "");
AmtPaid.Attributes.Remove("readonly");
}
else
{
AmtPaid.Text = string.Empty;
AmtPaid.Attributes.Add("readonly", "readonly");
}
}
The textbox get populated with the desired value when the checkbox is selected but both controls lost their values on pageindexchanging event.
I want the checkbox to maintain its state and textbox to maintain whatever value user entered when the pageindexchanging event is called.
Here is the code to move to next page
protected void gvPayment_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvPayment.PageIndex = e.NewPageIndex;
GetCustomer();
}
Note: I have gone through all suggested similar questions with no luck or success.
You have to persist them, for example by storing a Disctionary<int, bool> in the ViewState where the key is the RowIndex and the value is the bool(CheckBox is Checked?):
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["EnabledAmtPaidTextBoxes"] = new Dictionary<int, bool>();
GetCustomer();
}
}
I would encapsulate this logic in a method, you need to call it from RowDataBound and CheckedChanged. You don't need that final loop in GetCustomer anymore:
protected void gvPayment_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
EnabledAmtPaidTextBox(e.Row);
}
}
protected void chkSelect_CheckedChanged(object sender, EventArgs e)
{
CheckBox chkSelect = (CheckBox)sender;
GridViewRow row = (GridViewRow)chkSelect.NamingContainer;
EnabledAmtPaidTextBox(row, chkSelect.Checked);
}
private void EnabledAmtPaidTextBox(GridViewRow row, bool? newCheckedOrApplyOld = null)
{
TextBox AmtPaid = (TextBox)row.FindControl("AmtPaid");
Label AmtDue = (Label)row.FindControl("AmtDue");
CheckBox chkSelect = (CheckBox)row.FindControl("chkSelect");
Dictionary<int, bool> enabledAmtPaidTextBoxes = (Dictionary<int, bool>)ViewState["EnabledAmtPaidTextBoxes"];
if (!enabledAmtPaidTextBoxes.ContainsKey(row.RowIndex))
enabledAmtPaidTextBoxes[row.RowIndex] = false;
if (newCheckedOrApplyOld.HasValue)
enabledAmtPaidTextBoxes[row.RowIndex] = newCheckedOrApplyOld.Value;
else
chkSelect.Checked = enabledAmtPaidTextBoxes[row.RowIndex];
if (enabledAmtPaidTextBoxes[row.RowIndex])
{
AmtPaid.Text = AmtDue.Text.Replace(",", "");
AmtPaid.Attributes.Remove("readonly");
}
else
{
AmtPaid.Text = string.Empty;
AmtPaid.Attributes.Add("readonly", "readonly");
}
}
Also, if you use the using-statement you don't need con.Close and con.Dispose in finally because that is done by the using-statement already.

Column 'ID' does not belong to table DefaultView

I have a Gridview "Gridview_ActionPlan" with DataKey "ID" and a RowDataBound event that colors certain cells according to the value of the datasource. Until here everything fine. Now I added a command to give visibility to one column based on a condition and it throws the error "Column 'ID' does not belong to table DefaultView"
if (e.Row.Cells[3].Text != "1" && e.Row.Cells[2].Text != "2")
{
Gridview_ActionPlan.Columns[5].Visible = true;
LinkButton LB2 = e.Row.Cells[5].FindControl("ButtonOpen") as LinkButton;
LB2.Visible = true;
}
... and Columns[5]
<asp:templatefield ItemStyle-HorizontalAlign="center" Visible="false">
<ItemTemplate>
<asp:LinkButton ID="ButtonOpen" runat="server" CommandArgument = '<%# Eval("ID") %>' OnClick="OpenNode" style="vertical-align:text-bottom;text-decoration:none" Visible="false">
<asp:Image runat="server" src="img/plus_.png" id="OpenNodeIMG" border="0" Visible="true"/>
</asp:LinkButton>
</ItemTemplate>
</asp:templatefield>
Now if I give static visibility to that column and remove "Gridview_ActionPlan.Columns[5].Visible = true;" then no error is thrown. This doesn't make sense to me
Martin
Here is the full OnRowDataBound event:
Comment: The SQLConnection part fills the grid with the correct headers according to the chosen language. This is kind of time consuming so if someone has a better idea, feel free... although this is not the issue of that post
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
var gv = (GridView)sender;
string GridID = Convert.ToString(gv.ID);
SqlConnection objConn = new SqlConnection("Data Source=XXXXXX");
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommand objCommand = new SqlCommand(#"select Text
from EPC_Menu
where language = #language and MenuControlID = #GridID
order by MenuID", objConn);
objCommand.Parameters.Add("#GridID", SqlDbType.NVarChar).Value = GridID;
objCommand.Parameters.Add("#language", SqlDbType.NVarChar).Value = LanguageLabel.Text;
DataSet t = new DataSet();
adapter.SelectCommand = objCommand;
objConn.Open();
adapter.Fill(t);
objConn.Close();
if (e.Row.RowType == DataControlRowType.Header)
{
for(int i = 0; i+6 < gv.Columns.Count; i++)
{
if (t.Tables[0].Rows.Count > 0)
{
e.Row.Cells[i+6].Text = t.Tables[0].Rows[i][0].ToString();
}
}
}
else
{
if (e.Row.Cells[1].Text == "True")
{
e.Row.Cells[9].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
e.Row.Cells[10].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
}
else if (e.Row.Cells[2].Text == "2")
{
e.Row.BackColor = System.Drawing.ColorTranslator.FromHtml("#CCECF4");
}
if (e.Row.Cells[3].Text != "1" && e.Row.Cells[2].Text != "2" && !string.IsNullOrEmpty(e.Row.Cells[3].Text) && e.Row.RowType == DataControlRowType.DataRow && Gridview_ActionPlan.EditIndex != e.Row.RowIndex)
{
LinkButton LB2 = e.Row.Cells[5].FindControl("ButtonOpen") as LinkButton;
LB2.Visible = true;
}
}
}
here goes the gridview with columns 0 - 5 is already posted:
<asp:GridView ID="Gridview_ActionPlan" runat="server"
DataSourceID="ActionPlan"
DataKeyNames="ID"
AutoGenerateColumns="false"
Font-Names="Arial"
OnRowDataBound="OnRowDataBound">
<RowStyle BorderColor="White"
Font-Size="12px" VerticalAlign="Bottom" />
<Columns>
<asp:BoundField DataField="ID"
ItemStyle-CssClass="hiddencol"
HeaderStyle-CssClass="hiddencol" />
<asp:BoundField DataField="CustomerRequired"
ItemStyle-CssClass="hiddencol"
HeaderStyle-CssClass="hiddencol" />
<asp:BoundField DataField="Type"
ItemStyle-CssClass="hiddencol"
HeaderStyle-CssClass="hiddencol" />
<asp:BoundField DataField="CNT"
ItemStyle-CssClass="hiddencol"
HeaderStyle-CssClass="hiddencol" />
<asp:TemplateField ItemStyle-HorizontalAlign="left"
ItemStyle-Width="50px" Visible="false">
<ItemTemplate>
<asp:ImageButton ID="LINKButton2" runat="server"
CommandName="Edit"
ImageUrl="img/edit.png"
Style="vertical-align: text-bottom" />
<asp:LinkButton ID="ButtonSelect" runat="server"
CommandName="Select"
CommandArgument='<%# Eval("ID") %>'
Style="vertical-align: text-bottom; text-decoration: none"
OnClick="AddNewMileStone" Visible="true">
<asp:Image runat="server" ID="ImageMS"
ImageUrl="img/select.png"
Style="vertical-align: text-bottom; text-decoration: none"
BorderStyle="None" />
</asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
<asp:ImageButton ID="InsertButton" runat="server"
CommandName="Update"
ImageUrl="img/save.png"
Style="vertical-align: text-bottom" />
<asp:ImageButton ID="LINKButton2" runat="server"
CommandName="Cancel"
ImageUrl="img/cancel2.jpg"
Style="vertical-align: text-bottom" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-HorizontalAlign="center"
Visible="false">
<ItemTemplate>
<asp:LinkButton ID="ButtonOpen" runat="server"
CommandArgument = '<%# Eval("ID") %>'
OnClick="OpenNode"
style="vertical-align:text-bottom;text-decoration:none"
Visible="false">
<asp:Image id="OpenNodeIMG" runat="server"
src="img/plus_.png"
border="0"
Visible="true"/>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
This is kind of time consuming so if someone has a better idea, feel free... although this is not the issue of that post
Actually this should be a major issue. You are doing three things wrong here.
You are calling the function to fill the dataset in each iteration of RowDataBound. If you have 20 rows and 1 header that will be 20 unnecessary call to database
No need to open() the connection to fill a dataset using a data-adapter
No need to qualify .FindControl with Cells[cell_index]`.
So move your code after your Gridviews DataBind() event. Pseudo code will be,
Gridview_ActionPlan.DataBind();
DataSet t = new DataSet();
var gv = Gridview_ActionPlan;
string GridID = Convert.ToString(gv.ID);
using (SqlConnection objConn = new SqlConnection("Data Source=XXXXXX"))
using (SqlCommand objCommand = new SqlCommand(#"select Text
from EPC_Menu
where language = #language and MenuControlID = #GridID
order by MenuID", objConn))
{
SqlDataAdapter adapter = new SqlDataAdapter();
objCommand.Parameters.Add("#GridID", SqlDbType.NVarChar).Value = GridID;
objCommand.Parameters.Add("#language", SqlDbType.NVarChar).Value = LanguageLabel.Text;
adapter.SelectCommand = objCommand;
adapter.Fill(t);
}
var headerRow = gv.HeaderRow;
for (int i = 0; i + 6 < gv.Columns.Count; i++)
{
if (t.Tables[0].Rows.Count > 0)
{
headerRow.Cells[i + 6].Text = t.Tables[0].Rows[i][0].ToString();
}
}
for (int i = 0; i < gv.Rows.Count; i++)
{
if (gv.Rows[i].Cells[1].Text == "True")
{
gv.Rows[i].Cells[9].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
gv.Rows[i].Cells[10].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
}
else if (gv.Rows[i].Cells[2].Text == "2")
{
gv.Rows[i].BackColor = System.Drawing.ColorTranslator.FromHtml("#CCECF4");
}
if (gv.Rows[i].Cells[3].Text != "1" &&
gv.Rows[i].Cells[2].Text != "2" &&
!string.IsNullOrEmpty(gv.Rows[i].Cells[3].Text) &&
gv.Rows[i].RowType == DataControlRowType.DataRow &&
Gridview_ActionPlan.EditIndex != gv.Rows[i].RowIndex)
{
LinkButton LB2 = gv.Rows[i].FindControl("ButtonOpen") as LinkButton;
LB2.Visible = true;
}
}

How to show x-items in Repeater and scroll or fadein-fadeout next items using asp.net?

I have a repeater which displays 'News' on home page which is diplayed from database. I want to display just 2records at a time and automatically scrolling next two items after certain milliseconds with scrolling or fadein-fadeout effect.
In aspx page:
<asp:Repeater ID="RepDetails" runat="server" OnItemDataBound="RepDetails_ItemDataBound">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<div id="MainContent" style="border: 1px;">
<table>
<tr>
<td rowspan="2" class="auto-style2">
<img src="Images/lasts1.png" />
</td>
<td>
<asp:Label ID="lblNewsTitle" runat="server" Font-Bold="True" /></td>
<td> </td>
</tr>
<tr width="100px">
<td>
<asp:Label ID="lblNewsDescription" runat="server" /></td>
<td> </td>
</tr>
</table>
</div>
<hr />
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
In .cs Page:
protected void RepDetails_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
DataRowView dr = e.Item.DataItem as DataRowView;
string Id = Convert.ToString(dr["NewsID"]);
//HtmlGenericControl teammemberapp = e.Item.FindControl("teammemberapp") as HtmlGenericControl;
//Link to TeamMemberDetails Page
//teammemberapp.Attributes.Add("onclick", "window.location.href='NewsDetails.aspx?Id=" + Id + "'");
string newsTitle = Convert.ToString(dr["NewsTitle"]);
Label lblNewsDescription = e.Item.FindControl("lblNewsDescription") as Label;
Label lblNewsTitle = e.Item.FindControl("lblNewsTitle") as Label;
//set First Name Label
lblNewsTitle.Text = newsTitle;
string newsDescription = Convert.ToString(dr["NewsDescription"]);
if (newsDescription.Length > 50)
{
lblNewsDescription.Text = newsDescription.Substring(0, 50) + "..";
}
else
{
lblNewsDescription.Text = newsDescription;
}
}
}
public void GetRecord()
{
string connectionString = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString.ToString();
DataTable datatable = new DataTable();
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
connection.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "usp_NewsSelectYES";
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(datatable);
connection.Close();
}
//Bind Table to Repeater
RepDetails.DataSource = datatable;
RepDetails.DataBind();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Get all news with yes
GetRecord();
}
}
Help Appreciated!
Thanks!
Try to use some kind of jquery slider

DropDownList error 'does not exist in the in the list of items' ASP.NET C#

I was trying to make a custom application form. I've added some control like TextBox and Button so far everything is fine until I modified some of the TextBox with a DropDownList control. When I click the add button it returns an error:
'categoryDropDownList' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value
I've attached the sample code of my code behind:
public partial class Test2 : System.Web.UI.Page
{
public string GetConnectionString()
{
return System.Configuration.ConfigurationManager.ConnectionStrings["LibrarySystemConnectionString"].ConnectionString;
}
private void execution(string bookid, string booktitle, string lastname, string firstname, string description, string categoryid, string dateadded, string quantity, string statusid)
{
SqlConnection conn = new SqlConnection(GetConnectionString());
string sql = "INSERT INTO TblBooks(bookid, booktitle, lastname, firstname, description, categoryid, dateadded, quantity, statusid) VALUES "+" (#bookid, #booktitle,#lastname, #firstname, #description, #categoryid, #dateadded, #quantity, #statusid)";
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlParameter[] pram = new SqlParameter[9];
pram[0] = new SqlParameter("#bookid", SqlDbType.BigInt, 64);
pram[1] = new SqlParameter("#booktitle", SqlDbType.NVarChar, 50);
pram[2] = new SqlParameter("#lastname", SqlDbType.NVarChar, 50);
pram[3] = new SqlParameter("#firstname", SqlDbType.NVarChar, 50);
pram[4] = new SqlParameter("#description", SqlDbType.NVarChar, 200);
pram[5] = new SqlParameter("#categoryid", SqlDbType.Int, 32);
pram[6] = new SqlParameter("#quantity", SqlDbType.Int, 32);
pram[7] = new SqlParameter("#statusid", SqlDbType.Int, 32);
pram[8] = new SqlParameter("#dateadded", SqlDbType.DateTime, 32);
pram[0].Value = bookid;
pram[1].Value = booktitle;
pram[2].Value = lastname;
pram[3].Value = firstname;
pram[4].Value = description;
pram[5].Value = categoryid;
pram[6].Value = quantity;
pram[7].Value = statusid;
pram[8].Value = dateadded;
for (int i = 0; i < pram.Length; i++)
{
cmd.Parameters.Add(pram[i]);
}
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException ex_msg)
{
string msg = "Error occured while inserting";
msg += ex_msg.Message;
throw new Exception(msg);
}
finally
{
conn.Close();
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
if (bookidTextBox.Text == "")
{
Response.Write("Please complete the form");
}
else
{
execution(bookidTextBox.Text, booktitleTextBox.Text, lastnameTextBox.Text, firstnameTextBox.Text, descriptionTextBox.Text, categoryDropDownList.SelectedValue, dateaddedTextBox.Text, quantityTextBox.Text, statusDropDownList.SelectedValue);
//conform.Visible = true;
bookidTextBox.Text = "";
booktitleTextBox.Text = "";
lastnameTextBox.Text = "";
firstnameTextBox.Text = "";
descriptionTextBox.Text = "";
categoryDropDownList.SelectedValue = "";
dateaddedTextBox.Text = "";
statusDropDownList.SelectedValue = "";
quantityTextBox.Text = "";
}
}
}
}
Here's the sample code of the form:
<table class="style1">
<tr>
<td class="style2">
ISBN:
</td>
<td class="style3">
<asp:TextBox ID="bookidTextBox" runat="server" Text='<%# Bind("bookid") %>'>
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator" runat="server" ControlToValidate="bookidTextBox" ErrorMessage="* " ValidationGroup="addbooks">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td class="style2">
Title:
</td>
<td class="style3">
<asp:TextBox ID="booktitleTextBox" runat="server" Text='<%# Bind("booktitle") %>'>
</asp:TextBox>
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="booktitleTextBox" ErrorMessage="* " ValidationGroup="addbooks">
</asp:RequiredFieldValidator>
</td>
</tr>
... (cut some code here)
<tr>
<td class="style2">
Category:
</td>
<td class="style3">
<asp:DropDownList ID="categoryDropDownList" runat="server"
DataSourceID="categoryDataSource" DataTextField="name"
DataValueField="categoryid" >
</asp:DropDownList>
<asp:SqlDataSource ID="categoryDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:LibrarySystemConnectionString %>"
SelectCommand="SELECT [categoryid], [name] FROM [TblCategory]">
</asp:SqlDataSource>
</td>
</tr>
...
<tr>
<td class="style2">
Status:</td>
<td class="style3">
<asp:DropDownList ID="statusDropDownList" runat="server"
DataSourceID="statusDataSource" DataTextField="statusname"
DataValueField="statusid" >
</asp:DropDownList>
<asp:SqlDataSource ID="statusDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:LibrarySystemConnectionString %>"
SelectCommand="SELECT [statusid], [statusname] FROM [BookStatus]">
</asp:SqlDataSource>
</td>
</tr>
</table>
</div>
<asp:Button ID="AddBtn" runat="server" Text="Add" OnClick="Button1_Click" Width="100px" />
<br />
<br />
<b>Book List</b>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="bookid" DataSourceID="bookDataSource">
<Columns>
<asp:BoundField DataField="bookid" HeaderText="bookid" ReadOnly="True"
SortExpression="bookid" />
<asp:BoundField DataField="booktitle" HeaderText="booktitle"
SortExpression="booktitle" />
<asp:BoundField DataField="lastname" HeaderText="lastname"
SortExpression="lastname" />
<asp:BoundField DataField="firstname" HeaderText="firstname"
SortExpression="firstname" />
<asp:BoundField DataField="categoryid" HeaderText="categoryid"
SortExpression="categoryid" />
<asp:BoundField DataField="description" HeaderText="description"
SortExpression="description" />
<asp:BoundField DataField="dateadded" HeaderText="dateadded"
SortExpression="dateadded" />
<asp:BoundField DataField="statusid" HeaderText="statusid"
SortExpression="statusid" />
<asp:BoundField DataField="quantity" HeaderText="quantity"
SortExpression="quantity" />
<asp:CheckBoxField DataField="isdeleted" HeaderText="isdeleted"
SortExpression="isdeleted" />
</Columns>
</asp:GridView>
It worked when I try to convert the DropDownList to textbox but how can I bind it with a DropDownList control??
Help would be much appreciated! Thanks in advance.
Your DropDown is bound to SqlDataSource. When you execute categoryDropDownList.SelectedValue = "", the DropDown is looking for empty value in the data source, but can't find such, so it fails.
If might want to run dropDownList.ClearSelection() if this is what you are trying to achieve.
Here is simplified code example that would demonstrate the issue
protected void Page_Load(object sender, EventArgs e)
{
var items = new[] { new { Id = 1, Name = "Test1" }, new { Id = 2, Name = "Test2" } };
dropDownList.DataSource = items;
dropDownList.DataValueField = "Id";
dropDownList.DataTextField = "Name";
dropDownList.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
dropDownList.SelectedValue = ""; // trhows exception
dropDownList.ClearSelection(); // works
}
Read up on this:
http://msdn.microsoft.com/en-us/library/system.web.ui.page.enableeventvalidation.aspx

how to find datakeys in oncheckedchanged event?

<asp:Panel ID="pnlFocusAreaPanel" runat="server" GroupingText="Focus Area" Width="800">
<table cellspacing="0" cellpadding="0" width="750">
<tr>
<td>
<asp:GridView ID="dgFocusAreaDetails" runat="server" Width="100%" CssClass="dgStyle"
AutoGenerateColumns="False" BorderColor="Silver" BorderWidth="1px" CellPadding="0"
ShowHeader="False" OnSelectedIndexChanged="dgFocusAreaDetails_SelectedIndexChanged"
DataKeyNames="PK_ID">
<FooterStyle Font-Underline="True" HorizontalAlign="Center" VerticalAlign="Middle">
</FooterStyle>
<Columns>
<asp:TemplateField HeaderText="Focus Area" HeaderStyle-BackColor="Silver">
<ItemStyle Width="90%" />
<ItemTemplate>
<asp:Label runat="server" ID="lblFocusArea" Text='<%# DataBinder.Eval(Container.DataItem, "FOCUS_AREA_NAME").ToString()%>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Is Current Valid" HeaderStyle-BackColor="Silver">
<ItemStyle Width="10%" HorizontalAlign="Center" />
<ItemTemplate>
<asp:CheckBox ID="chkFocusArea" runat="server" OnCheckedChanged="OnCheckChangedEvent"
AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</td>
</tr>
<tr>
<td align="left">
<asp:TextBox ID="txtFocusArea" runat="server" Width="300px" CausesValidation="true" CssClass="txtStyle" ValidationGroup="focusArea">
</asp:TextBox>
<cc1:TextBoxWatermarkExtender ID="txtFocusAreaWaterMark" runat="server" TargetControlID="txtFocusArea"
WatermarkText="Add Focus Area" WatermarkCssClass="WaterMarkStyle">
</cc1:TextBoxWatermarkExtender>
<asp:Button ID="btnAddFocusArea" runat="server" Text="AddFocusArea" CssClass="btnStyle"
OnClick="btnAddFocusArea_Click" CausesValidation="true" ValidationGroup="focusArea" />
<asp:RequiredFieldValidator ID="reqtxtFocusArea" runat="server" ControlToValidate="txtFocusArea"
ErrorMessage="Please enter focus area" Display="Dynamic" ValidationGroup="focusArea">
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regexFocusArea" runat="server" ErrorMessage="Invalid characters(<,>,#)"
ControlToValidate="txtFocusArea" ValidationExpression="^([^<#>]*)$" ValidationGroup="focusArea"
Display="Dynamic" SetFocusOnError="true">
</asp:RegularExpressionValidator>
</td>
</tr>
</table>
</asp:Panel>
and in code behind
protected void btnAddFocusArea_Click(object sender, EventArgs e)
{
string strFocusArea = txtFocusArea.Text;
OleDbConnection myConnection = new OleDbConnection(ConfigurationSettings.AppSettings["SQLConnectionString"]);
if (strFocusArea == string.Empty || strFocusArea == txtFocusAreaWaterMark.WatermarkText)
{
lblError.Text = "Focus area is not entered";
}
else
{
string insertQuery = "INSERT INTO LK_CODECAT_FOCUS_AREA(FOCUS_AREA_NAME,FK_ADDED_BY,ADDED_ON) "+
" VALUES('" + strFocusArea + "', "+Session["UserID"] +", GETDATE())";
try
{
myConnection.Open();
OleDbCommand myCommandToInsert = new OleDbCommand(insertQuery, myConnection);
myCommandToInsert.ExecuteNonQuery();
}
catch(Exception exc)
{
ExceptionLogger.LogException(exc);
}
finally
{
if (myConnection != null)
{
myConnection.Close();
}
}
PopulateFocusArea();
}
txtFocusArea.Text = txtFocusAreaWaterMark.WatermarkText;
}
private void PopulateFocusArea()
{
OleDbConnection myConnection = new OleDbConnection(ConfigurationSettings.AppSettings["SQLConnectionString"]);
string selectQuery = "SELECT PK_ID, FOCUS_AREA_NAME, IS_CURRENT_FOCUS FROM LK_CODECAT_FOCUS_AREA LKCFA ORDER BY FOCUS_AREA_NAME";
if (Session["RoleID"].ToString() == "1" || ((Session["WorkID"].ToString() != "9") ||
(Session["WorkID2"].ToString() != "9") ||
(Session["WorkID3"].ToString() != "9")))
{
try
{
myConnection.Open();
OleDbCommand myCommandFocusArea = new OleDbCommand(selectQuery, myConnection);
OleDbDataAdapter myAdapter = new OleDbDataAdapter(myCommandFocusArea);
DataSet ds = new DataSet();
myAdapter.Fill(ds);
dgFocusAreaDetails.DataSource = ds;
dgFocusAreaDetails.ShowHeader = true;
dgFocusAreaDetails.DataBind();
}
catch (Exception exc)
{
ExceptionLogger.LogException(exc);
}
finally
{
if (myConnection != null)
{
myConnection.Close();
}
}
}
}
protected void dgFocusAreaDetails_SelectedIndexChanged(object sender, EventArgs e)
{
string selectedCategory = dgFocusAreaDetails.SelectedRow.Cells[1].Text;
int index = dgFocusAreaDetails.SelectedIndex;
lblError.Text = dgFocusAreaDetails.DataKeys[index].Value.ToString();
}
public void OnCheckChangedEvent(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
string chkfocusarea = ((Control)chk).ID;
//string focusAreaDetails = dgFocusAreaDetails.SelectedRow.Cells[0].Text;
int index =Convert.ToInt32(dgFocusAreaDetails.SelectedIndex);
if (chk.Checked)
{
string updateQuery = "UPDATE [LK_CODECAT_FOCUS_AREA] SET [IS_CURRENT_FOCUS] = 1 WHERE PK_ID = "
+Convert.ToInt32( dgFocusAreaDetails.DataKeys[index].Value)+" ";
}
else
{
lblError.Text = "unchecked";
}
}
i want to know how i find the datakeyvalue on checked event because updateQuery in checked event is generating exception.
Could you add a asp:button instead of using the checkbox on your GridView and fire an OnRowUpdating event?
Alternatively you could store the index value in a session varaible to pick up on your chkbox click.
edit: found this post is that any help?
They suggest you have to check each row to see if the value has changed.

Categories

Resources