C# CheckBoxList update in SQL Server - c#

Please inspect my C# code below and let me know where I am going wrong. Here is what I am experiencing:
1.) If I empty the SendReport column in SQL Server and load the page, the second row of the SendReport automatically gets populated with a 1.
2.) I can place a checkmark, click the button and the SendReport values successfully populate in SQL Server. However, if I uncheck any of them and click the button, none of the values change from 1 to 0. Please help!
$<asp:CheckBoxList ID="CheckBoxList1" runat="server">
</asp:CheckBoxList>
<br />
<asp:Button ID="Button1" runat="server" Text="Save Changes" OnClick="Button1_Click" />
<br />
BACKPAGE:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindCheckBoxList();
}
}
// Setting up the ConnectionString
public string GetConnectionString()
{
return System.Configuration.ConfigurationManager.ConnectionStrings["IPdataConnectionString"].ConnectionString;
}
// Binding the CheckBoxList with Data
private void BindCheckBoxList()
{
DataTable dt = new DataTable();
SqlConnection connection = new SqlConnection(GetConnectionString());
try
{
connection.Open();
string sqlStatement = "SELECT Partner, ID, SendReport FROM Rorts";
SqlCommand sqlCmd = new SqlCommand(sqlStatement, connection);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCmd);
sqlDa.Fill(dt);
if (dt.Rows.Count > 0)
{
CheckBoxList1.DataSource = dt;
CheckBoxList1.DataTextField = "Partner"; // the items to be displayed in the list items
CheckBoxList1.DataValueField = "SendReport"; // the id of the items displayed
CheckBoxList1.DataBind();
//Setting the Selected Items in the ChecBoxList based from the value in the database
//to do this, lets iterate to each items in the list
for (int i = 0; i < dt.Rows.Count; i++)
{
if (!string.IsNullOrEmpty(dt.Rows[i]["SendReport"].ToString()))
{
CheckBoxList1.Items[i].Selected = Convert.ToBoolean(dt.Rows[i]["SendReport"]);
}
}
}
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Fetch Error:";
msg += ex.Message;
throw new Exception(msg);
}
finally
{
connection.Close();
}
}
// Creating the Method for Saving the CheckBoxList Selected Items to the database
private void Update(string name, bool SendReport)
{
SqlConnection connection = new SqlConnection(GetConnectionString());
SqlCommand cmd;
string sqlStatement = string.Empty;
try
{
// open the Sql connection
connection.Open();
sqlStatement = "UPDATE Rorts SET SendReport = #SendReport WHERE Partner = #Partner";
cmd = new SqlCommand(sqlStatement, connection);
cmd.Parameters.AddWithValue("#Partner", name);
cmd.Parameters.AddWithValue("#SendReport", SendReport);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
catch (System.Data.SqlClient.SqlException ex)
{
string msg = "Insert/Update Error:";
msg += ex.Message;
throw new Exception(msg);
}
finally
{
// close the Sql Connection
connection.Close();
}
}
// Calling the Method for Saving the state of CheckBoxList selected items
protected void Button1_Click(object sender, EventArgs e)
{
string PartnerName = string.Empty;
for (int i = 0; i < CheckBoxList1.Items.Count; i++)
{
if (CheckBoxList1.Items[i].Selected)
{
PartnerName = CheckBoxList1.Items[i].Text;
Update(PartnerName, CheckBoxList1.Items[i].Selected);
}
}
//ReBind the List to retain the selected items on postbacks
BindCheckBoxList();
}

It looks like the issue is due to the if block below from the Button1 click event handler. The result is that only the check boxes that are checked have the values persisted to the database.
if (CheckBoxList1.Items[i].Selected)
{
PartnerName = CheckBoxList1.Items[i].Text;
Update(PartnerName, CheckBoxList1.Items[i].Selected);
}
You can just remove the if statement and persist all of the values or add logic to only persist those that have changed.

Related

How get list from SQL Server database with stored procedure and add to ComboBox

I need get list from my SQL Server database with a stored procedure and add all to combobox.
When I select any item from cBoxWhatLaws - the app connecting with database and gets relevant articles and add to cBoxArticleList.
Helper.WhatLaws returns tableName..
Stored procedure and database are ok, because all work with java application.
Adding to database from this application works too.
//Page.cs
private void cBoxWhatLaws_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (cBoxWhatLaws.SelectedIndex != 0)
{
tableName = Helper.WhatLaws(cBoxWhatLaws.SelectedIndex);
cBoxArticleList.Items.Clear();
cBoxArticleList.Items.Add("Choose article:");
if (MyDatabaseHelper.seeArtList(tableName).Count == 1)
{
MessageBox.Show("Article list is empty.", "Empty list", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
for (int i = 0; i < MyDatabaseHelper.seeArtList(tableName).Count; i++)
{
cBoxArticleList.IsEnabled = true;
cBoxArticleList.Items.Add(MyDatabaseHelper.seeArtList(tableName).ElementAt(i).ToString());
}
}
}
}
// MyDatabaseHelper
static SqlConnection sqlCon = new SqlConnection("Data Source=.; Initial Catalog=PrzepisyGry; Integrated Security=True;");
public static List<string> seeArtList(string przepisyGry)
{
var artList = new List<string>();
try
{
SqlCommand sqlCmd = new SqlCommand("getArticleList", sqlCon);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.Add(new SqlParameter("#nazwaTabeli", przepisyGry));
sqlCon.Open();
IDataReader result = sqlCmd.ExecuteReader();
int i = 0;
while (result.Read())
{
artList.Add(result[i].ToString());
i++;
}
}
catch
{
MessageBox.Show("Error with get list", "Err", MessageBoxButton.OK, MessageBoxImage.Error);
}
return artList;
}
The application has a problem with returning artList and shows an error:
Error with get list > Index out of range
I have a answer. In MyDatabaseHelper.cs:
while (result.Read())
{
artList.Add(result[0].ToString()); // i -> 0 (for first column)
}

Combo Box on dropdown method only called once

I am using two combo boxes in one of my programs. The first combo box contains the products while the second contains the categories. I have a method which loads he categories on the second combo box from the database when ever a new item is selected on the first combo box "products". The first time i run the program and select an item it loads from the database but if i try it again nothing loads. Please help with what might be causing this.
private void load_schemes(object sender, EventArgs e)
{
DataTable subjects = new DataTable();
DBConnect con = new DBConnect();
using (SqlConnection CONN = con.getConnection())
{
try
{
schemename.Items.Clear();
SqlDataAdapter adapter = new SqlDataAdapter();
String schemeType = schemetype.Text;
firstname.Text = schemetype.Text;
String SQL = "";
if (schemeType == "Family Scheme")
{
SQL = "select schemeID,SCHEMENAME from registration.familyMedicalScheme";
}
else if (schemeType == "Insurance Scheme")
{
SQL = "select schemeID,SCHEMENAME from registration.insurancescheme";
}
else if (schemeType == "Company Scheme")
{
SQL = "select schemeID,SCHEMENAME from registration.companymedicalscheme";
}
adapter.SelectCommand = new SqlCommand(
SQL, CONN);
adapter.Fill(subjects);
schemename.DataSource = subjects;
schemename.DisplayMember = "SCHEMENAME";
//schemename.ValueMember = subjects.;
}
catch (Exception ex)
{
// Handle the error
}
finally
{
CONN.Close();
}
}
}
I changed the solution and used Items.Add instead of data binding method and it is now working
adapter.Fill(subjects);
foreach (DataRow da in subjects.Rows)
{
schemename.Items.Add(da[0].ToString());
}

Delete all the data from the gridview

I want to implement a button on a web page which deletes all the data that has been shown on the gridview. Is there any simpler way to delete all data at once with the button?
It's very simple to do. Just iterate over each row in the gridview with and get the primary key value, then using the sql query to delete the record from the database.
The code here can help you. I am using the NorthWind sample database.
void loaddata()
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["TestDatabaseConnectionString"].ConnectionString);
SqlCommand command = new SqlCommand();
connection.Open();
try
{
command = connection.CreateCommand();
command.CommandText = "SELECT * FROM Employees";
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataTable datatable = new DataTable();
adapter.Fill(datatable);
GridView1.DataSource = datatable;
}
catch (Exception)
{
throw;
}
finally
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
int employee_id;
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["TestDatabaseConnectionString"].ConnectionString);
SqlCommand command = new SqlCommand();
connection.Open();
try
{
command = connection.CreateCommand();
for (int i = 0; i < GridView1.Rows.Count; i++)
{
employee_id = Convert.ToInt32(GridView1.Rows[i].Cells[0].Text);
command.CommandText = "DELETE FROM Employees WHERE EmployeeID = '" + employee_id + "'";
command.ExecuteNonQuery();
}
}
catch (Exception)
{
throw;
}
finally
{
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
}
loaddata();
}
You can always just set the DataSource to null.
someGridView.DataSource = null;
someGridView.DataBind();
I can only be as vague as the question and I still don't quite understand why I can't leave comments, but I can leave an answer...
Anyway, we don't know what you're using to access your database or the model backing the GridView.
Let's say for instance you have the following class backing your GridView (the type of data your GridView consists of that you've set the Datasource to):
public class MyData
{
public int ID { get; set; }
public string SomeData { get; set; }
}
In your ASPX you'd have the following:
<asp:GridView ID="GridView" runat="server"></asp:GridView>
<asp:Button ID="DeleteButton" runat="server" OnClick="DeleteButton_Click"/>
And then in your code-behind, you'd do something like this...
protected void DeleteButton_Click(object sender, EventArgs e)
{
var gridViewItemsToDelete = (IEnumerable<MyData>)GridView.DataSource;
foreach (var idToDelete in gridViewItemsToDelete.Select(r=>r.ID))
{
// Delete the item by its ID
// I don't know what you're using to access your database
}
// Save Changes if you didn't in the foreach loop...
}

Multiple CheckedListBox and database connections

I'm loading a table from a database into a CheckedListBox, and now I need to check which items are checked any time the user changes the check status of an item in the first CheckedListBox, and then add the corresponding parts of another table from my database to the second CheckedListBox.
So for example, I have chlbMeal and chlbFood. Inside the chlbMeal there are "Breakfast", "Dinner" and "Lunch". Now when the user selects any of these, I want the corresponding food options to show up in the chlbFood - for example, if "Breakfast" is checked, inside chlbFood we have "Fried eggs", "Eggs and Bacon", etc.
My project is somewhat different but that's the main the idea I want to achieve in this part of it. Here is my code:
private void chlbRadovi_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (chlbRadovi.CheckedItems.Count > 0)
{
int[] niz = new int[chlbRadovi.CheckedIndices.Count];
chlbRadovi.CheckedIndices.CopyTo(niz, 0);
foreach (int x in niz)
{
this.tipradovaTableAdapter1.Fill(this.ignaDataSet1.tipradova);
SqlConnection con = new SqlConnection(Konekcija.con);
SqlCommand cmd = new SqlCommand("select IDTR, Naziv from tipradova where IDRad in #IDRad", con);
cmd.Parameters.AddWithValue("#IDRad", chlbRadovi.ValueMember[x]);
SqlDataReader reader;
chlbTipoviRadova.DataSource = ignaDataSet1.tipradova;
chlbTipoviRadova.DisplayMember = "Naziv";
chlbTipoviRadova.ValueMember = "IDTR";
con.Open();
reader = cmd.ExecuteReader();
con.Close();
}
}
else
{
chlbTipoviRadova.DataSource = null;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
How can I do this?
Ok, here we go. First, bind data to your first CheckedListbox:
private string connectionString = "Your connection string";
private void cbListFirst_SetDataSource()
{
// Using block will automatically close connection when it's not used anymore
using (var con = new SqlConnection(connectionString))
{
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"SELECT Id, Name
FROM dbo.FoodTypes";
try
{
con.Open();
var foodTypes = new List<FoodType>();
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Fill items for first CheckedListBox DataSource
while (reader.Read())
{
foodTypes.Add(new FoodType()
{
Id = (int)reader["Id"],
Name = reader["Name"] as string
});
}
}
// Set first CheckedListBox DataSource
cbListFirst.DataSource = foodTypes;
cbListFirst.DisplayMember = "Name";
cbListFirst.ValueMember = "Id";
}
catch (Exception ex)
{
// Clear DataSource and handle error (should be improved)
cbListFirst.DataSource = null;
MessageBox.Show("Error", ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
After you've done that, you should have ParentIds encapsulated inside your FoodType objects inside DataSource of your first CheckedListbox. Now, you shouldn't use SelectedIndexChanged event, but ItemCheck event instead. So every time user checks or unchecks one of the items event will be triggered. Only problem you have now is that inside this event, new CheckValue of clicked item is not yet applied, but it can be handled easy since we have information about new and old value inside EventArgs. Check this out:
private void cbListFirst_ItemCheck(object sender, ItemCheckEventArgs e)
{
// Clear second CheckedListbox DataSource
cbListSecond.DataSource = null;
var ingridients = new List<Ingridient>();
foreach (var item in cbListFirst.CheckedItems)
{
// If item was previously checked, we want to skip it because it's new value is
// unchecked and we shouldn't be adding it's child items to second CheckedListbox
if (cbListFirst.Items.IndexOf(item) != e.Index)
{
var foodType = (FoodType)item;
ingridients.AddRange(GetIngridientsForFoodType(foodType.Id));
}
}
// If item was previously unchecked, it's child items won't be caught in previous loop
// so we want to explicitly include them inside this if-block if new value is checked
if (e.NewValue == CheckState.Checked)
{
var foodType = (FoodType)cbListFirst.Items[e.Index];
ingridients.AddRange(GetIngridientsForFoodType(foodType.Id));
}
// Finally, bind new DataSource
cbListSecond.DataSource = ingridients;
cbListSecond.DisplayMember = "Name";
cbListSecond.ValueMember = "Id";
}
// This method returns list of Ingridients for single FoodType
private List<Ingridient> GetIngridientsForFoodType(int foodTypeId)
{
using (var con = new SqlConnection(connectionString))
{
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"SELECT Id, Name
FROM dbo.Ingridients
WHERE FoodTypeId = #FoodTypeId";
cmd.Parameters.AddWithValue("#FoodTypeId", foodTypeId);
try
{
con.Open();
var ingridients = new List<Ingridient>();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
ingridients.Add(new Ingridient()
{
Id = (int)reader["Id"],
Name = reader["Name"] as string
});
}
}
return ingridients;
}
catch (Exception ex)
{
// Handle error (should be improved) and return null
MessageBox.Show("Error", ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
}
}
Now your second CheckedListbox should be filled with child values of items from first CheckedListbox.

Sql command doesn't display table

I have this code behind button that displays table in SQL when the button is pressed.
I cant seem to know that problem why it doesn't display any table?
I added this line of code to check if the BatchID is out of range in the sql table
if (read.Read())
{
GridView1.DataSource = read;
GridView1.DataBind();
}
else
{
lbl_NoBatchID.Text = "BatchID out of range";
}
protected void Button1_Click(object sender, EventArgs e)
{
if (DropDownList1.SelectedItem.ToString() =="ER00 - File Header")
{
using (SqlConnection con = new SqlConnection(ConfigurationSettings.AppSettings["DBcon"]))
{
if (String.IsNullOrEmpty(TextBox_ID.Text.ToString()))
{
lbl_NoBatchID.Text = "Please enter BatchID!";
}
else
{
try
{
lbl_NoBatchID.Text = "";
SqlCommand sqlCommand = new SqlCommand("Select * from tbl_WinApps_FileHeader Where BatchID =" + TextBox_ID.Text.ToString());
sqlCommand.Connection = con;
con.Open();
SqlDataReader read = sqlCommand.ExecuteReader();
if (read.Read())
{
GridView1.DataSource = read;
GridView1.DataBind();
}
else
{
lbl_NoBatchID.Text = "BatchID out of range";
}
}
catch (Exception)
{
}
}
}
}
Make sure you do two things.
1.) Close the DataReader after Databind().
2.) Set AutoGenerateColumns="True" for your GridView.

Categories

Resources