C# Foreach item in CheckedListBox only gets one item - c#

When I check more than one item in the CheckedListBox, than it only gets the Selected.Value of the last selected item and uses that for the amount of times the foreach is used.
Extra context: It's an application that can put exercises on certain days, so it's a workout app, but when you select more than 1 exercise in the CheckedListBox, than it only adds items with the last selected value.
So selects 3 different items(pushups, pullups, situps) --> 3 situps get added with all the same values.
Code that adds exercises to the other normal ListBox:
query = "INSERT INTO Xercise_Day (DayId, ExerciseId) " +
"VALUES(#DayId, #ExerciseId)";
foreach (CheckedListBox exercise in clbXcercises.CheckedItems)
{
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#DayId", scrollBarDays.Value);
command.Parameters.AddWithValue("#ExerciseId", clbXcercises.SelectedValue);
DataTable data = new DataTable();
adapter.Fill(data);
lsBoxDailyX.DataSource = data;
lsBoxDailyX.DisplayMember = "Naam";
}
DailyX();
}
for(int i = 0; i < clbXcercises.Items.Count; i++)
{
clbXcercises.SetItemChecked(i, false);
}

As stated in the comments, reference exercise instead of clbXcercises to get the selected value. The code becomes:
foreach (object exercise in clbXcercises.CheckedItems)
{
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#DayId", scrollBarDays.Value);
command.Parameters.AddWithValue("#ExerciseId", exercise.ToString());
DataTable data = new DataTable();
adapter.Fill(data);
lsBoxDailyX.DataSource = data;
lsBoxDailyX.DisplayMember = "Naam";
}
DailyX();
}

Related

Inserting selected items from a ListBox into MSSQL database with ADO.NET (c#)

I would like to know how to insert selected items from a ListBox into a MSSQL Database.
I am developing an ASP.NET web app and this is the problem:
I have a Listbox named lbxRuoli and items are loaded directly from the database:
SqlCommand cmd = new SqlCommand("select descrizione_Ruoli, id_Ruoli from Ruoli", conn);
SqlDataReader dr = cmd.ExecuteReader();
ListItem li = new ListItem("- SELEZIONA -", "");
lbxRuoli.Items.Add(li);
while (dr.Read())
{
li = new ListItem(dr["descrizione_Ruoli"].ToString(), dr["id_Ruoli"].ToString());
lbxRuoli.Items.Add(li);
}
dr.Close();
cmd.Dispose();
Now it comes to write the INSERT for the selected items:
for (int i = 0; i < lbxRuoli.Items.Count; i++)
{
if (lbxRuoli.Items[i].Selected == true)
{
cmd = new SqlCommand("insert into [Utenti.Ruoli] (id_Utenti, id_Ruoli) values(#id, #idR)", conn);
cmd.Parameters.AddWithValue("#id", txtId.Text);
cmd.Parameters.AddWithValue("#idR", lbxRuoli.SelectedValue);
cmd.ExecuteNonQuery();
}
}
It happens that I only insert the same first selected item for the total numbers of the selected items.
It would be wonderful if someone can help me!
Thanks to every one in advance!
Connections need to be not only closed but disposed to release unmanaged objects. using blocks handle this even if there is an error.
Commands also need to be disposed. To accomplish this they should be declared local to the method where they are used. using blocks will close and dispose you database objects.
You don't want to hold a connection open while you update the user interface. Fill a DataTable, close the connection (the using block does it) and then fill the ListBox from the DataTable.
To insert the data create the connection, command and fill the parameters collection outside the loop. Only the values of the parameters change inside the loop
The code below demonstrates how to use the .Add method for parameters. I had to guess at the type and size of the parameters. Check your database and adjust the code accordingly making sure that the parameter values are compatible with the SqlDbType.
private string ConStr = "Your connection string";
private DataTable GetListData()
{
DataTable dt = new DataTable();
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("select descrizione_Ruoli, id_Ruoli from Ruoli", cn))
{
cn.Open();
dt.Load(cmd.ExecuteReader());
}
return dt;
}
private void FillListBox()
{
DataTable dt = GetListData();
ListItem li = new ListItem("- SELEZIONA -", "");
lbxRuoli.Items.Add(li);
foreach (DataRow row in dt.Rows)
{
li = new ListItem(row["descrizione_Ruoli"].ToString(), row["id_Ruoli"].ToString());
lbxRuoli.Items.Add(li);
}
}
private void InsertData()
{
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("insert into [Utenti.Ruoli] (id_Utenti, id_Ruoli) values(#id, #idR)", cn))
{
cmd.Parameters.Add("#id", SqlDbType.VarChar, 20);
cmd.Parameters.Add("#idR", SqlDbType.VarChar, 20);
cn.Open();
foreach (ListItem li in lbxRuoli.Items)
{
if (li.Selected)
{
cmd.Parameters["#id"].Value = li.Text;
cmd.Parameters["idR"].Value = li.Value;
cmd.ExecuteNonQuery();
}
}
}
}

Inserting variables as well as columns using SqlBulkCopy

I'm just learning and have written this code to copy data from one database to another (LOTSCON) = source, CON = destination.
The code all works and copies the data across, however it is based on checkboxes on a previous datagridview form.
The user selects which records to import, but also selects CHKCOMMUNITY which means this patient is a nursing home patient.
In the NEW table, there is a column nursinghome which is a bit type.
If the user ticks chkCommunity in the datagrid, I want to do the bulk copy but also make sure the nursinghome column in the destination table is set to 1.
So I'm not mapping an existing column in the source table..
How can I achieve this?
DO I just import then run a SQL string updating the column based on what I have just entered?
foreach (DataGridViewRow row in dataGridInst.Rows)
{
DataGridViewCheckBoxCell chkcell = row.Cells["chkimport"] as DataGridViewCheckBoxCell;
if (chkcell.Value != null)
{
if (Convert.ToBoolean(chkcell.Value) == true)
{
instid = Convert.ToInt32(row.Cells["clninstid"].Value);
iscommunity = Convert.ToInt32(row.Cells["chkcommunity"].Value);
using (SqlConnection lotscon = new SqlConnection(ConfigurationManager.ConnectionStrings["LOTSConnectionString"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(#"SELECT Person.*, NEWinstitution.institutionname
FROM NEWinstitution INNER JOIN Person ON NEWinstitution.institutionid = Person.InstitutionID
WHERE person.institutionid = #instid", lotscon))
{
cmd.Parameters.Add("#instid", SqlDbType.Int).Value = instid;
using (SqlDataAdapter adapt = new SqlDataAdapter())
{
adapt.SelectCommand = cmd;
lotscon.Open();
DataSet ds = new DataSet();
adapt.Fill(ds);
DataTable dtgenerate = new DataTable();
dtgenerate = ds.Tables[0];
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString))
{
using (SqlBulkCopy bc = new SqlBulkCopy(con))
{
bc.DestinationTableName = "tblpatient";
bc.ColumnMappings.Add("firstname", "pxfirstname");
bc.ColumnMappings.Add("lastname", "pxlastname");
bc.ColumnMappings.Add("address", "address");
bc.ColumnMappings.Add("suburb", "suburb");
bc.ColumnMappings.Add("medicareno", "medicarenumber");
bc.ColumnMappings.Add("personid", "dispenseid");
bc.ColumnMappings.Add("institutionname", "institutionname");
bc.ColumnMappings.Add("VAcardid", "repatnumber");
bc.ColumnMappings.Add("phonenumber", "phonenumber");
con.Open();
bc.WriteToServer(dtgenerate);
con.Close();
lotscon.Close();
}
}
}
}
}
}
}
}

Dataset Loading a WPF Combobox

DataSet dataSet = new DataSet();
using (SqlConnection connection = new SqlConnection("server=server; database=database; user id=user; password=user"))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT DISTINCT ID FROM TABLE ORDER BY ID ASC", connection))
{
SqlDataAdapter reader = new SqlDataAdapter(command);
reader.Fill(dataSet);
IDComboBox.DataContext = dataSet; --> This doesn't work
IDComboBox.Itemsource = dataSet.Tables[0].Columns[0].ToString() --> doesn't work
IDComboBox.Itemsource = dataSet.Tables[0].Rows[0].ToString() --> doesn't work
IDComboBox.Itemsource = dataSet.Tables[0].Rows --> doesn't work
IDComboBox.Itemsource = dataSet.Tables[0].Columns --> doesn't work
They don't work even with me pairing it the IDComboBox.DataContext = dataSet.Tables[0].Rows[0] or Columns[0]
}
connection.Close();
connection.Dispose();
}
I am needing to fill my combobox in a WPF with the data from my datatable. All I keep finding are the examples that use Combobox.Displaymember, Combobox.Source to do this but a C# WPF application doesn't have these options. How can I load a WPF combobox with data from a dataset or a datatable?
One way that I was doing it before was
using (SqlConnection connection = new SqlConnection("server=server; database=database; user id=user; password=user"))
{
connection.Open();
using (SqlCommand command = new SqlCommand("SELECT DISTINCT ID FROM Table ORDER BY ID ASC", connection))
{
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
IDComboBox.Items.Add(reader[i].ToString());
}
}
}
connection.Close();
connection.Dispose();
}
I know having it for looped into my combobox is very slow if I have large amounts of data so I am wanting to dump it in from a dataset to reduce run time.
Derived from this example, you'll want to work with the ItemSource, DisplayMemberPath, and SelectedValuePath properties:
IDComboBox.ItemsSource = dataSet.Tables[0].DefaultView;
IDComboBox.DisplayMemberPath = dataSet.Tables[0].Columns["ID"].ToString();
IDComboBox.SelectedValuePath = dataSet.Tables[0].Columns["ID"].ToString();
And in xml:
<ComboBox Name="IDComboBox" ItemsSource="{Binding}"/>
The WPF ComboBox has an ItemSource property you can use.
IDComboBox.ItemsSource = dataSet.Tables[0].Rows;

inserting into data sourced combobox

i am working on visual studio 2012 c# ...
i inserted values into the combox ...i took them from database...I WANT TO KNOW HOW CAN I ADD AN ITEM TO THE COMBOBOX ...ill show u the code below:
Here this function to fill the combobox with names taken from a table in database containig name and id:
List<Lookup> fillCombo(string query, string column)
{
List<Lookup> lookups = new List<Lookup>();
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Lookup lookupobject = new Lookup();
lookupobject.ID = Convert.ToInt32(reader["ID"]);
//if (reader["Name"] != DBNull.Value)
lookupobject.Name = reader[column].ToString();
lookups.Add(lookupobject);
}
conn.Close();
}
return lookups;
}
then i call this function as follows:
lookups = fillCombo("select id,name from LookupDetails where LOOKUPID = (select id from Lookup where Name = 'users')", "name");
comboBox2.DataSource = lookups;
comboBox2.DisplayMember = "name";
ComboxBox Items collection cannot be modified when the DataSource property is set.
You got the options of either modifying the List<Lookup> or by adding items into combox by iterating over the List<Lookup>.
Here is option to add items in combobox using foreach loop and insert item at 0 index of comboxbox:
lookups = fillCombo(#"select id,name from LookupDetails where LOOKUPID =
(select id from Lookup where Name = 'users')", "name");
foreach(var obj in lookups)
comboBox2.Items.Add(obj);
comboBox2.DisplayMember = "Name";
comboBox2.Items.Insert(0, "");
Note: In the code mentioned in the question, SqlDataReader was never closed, I have modified it by including using statement. You don't have to close SqlDataReader or SqlConnection when you write these in using block:
List<Lookup> fillCombo(string query, string column)
{
List<Lookup> lookups = new List<Lookup>();
string sConstring = ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString;
using (SqlConnection conn = new SqlConnection(sConstring))
using(SqlCommand cmd = new SqlCommand(query, conn))
{
conn.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Lookup lookupobject = new Lookup();
lookupobject.ID = Convert.ToInt32(reader["ID"]);
//if (reader["Name"] != DBNull.Value)
lookupobject.Name = reader[column].ToString();
lookups.Add(lookupobject);
}
}
}
return lookups;
}

How can I populate a list with values from a SQL Server database?

The list will grow and shrink depending on how many items I have in my database.
I need to populate a list not a listbox. I understand I will need to open a connection.
using (var conn = new SqlConnection(Properties.Settings.Default.DBConnectionString))
{
using (var cmd = conn.CreateCommand())
{
conn.Open();
List<string> TagList = new List<string>();
for (int i = 0; i < TagList.Count; i++)
TagList[i].Add("Data from database");
cmd.ExecuteNonQuery();
}
}
I'm really not sure how to do this and I'm sure my method up here looks very wrong so I really need help.
Could someone show me what I'm doing wrong?
public IEnumerable<string> GetTagList()
{
using (var connection = new SqlConnection(Properties.Settings.Default.DBConnectionString))
using (var cmd = connection.CreateCommand())
{
connection.Open();
cmd.CommandText = "select Tag from TagsTable"; // update select command accordingly
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
yield return reader.GetString(reader.GetOrdinal("Tag"));
}
}
}
}
then you can call it as below
List<string> tags = GetTagList().ToList();
I would like to share my solution, hope helps someone in the future:
public List<string> getFromDataBase()
{
List<string> result = new List<string>();
using(SqlConnection con = new SqlConnection("connectionString"))
{
con.Open();
DataTable tap = new DataTable();
new SqlDataAdapter(query, con).Fill(tap);
result = tap.Rows.OfType<DataRow>().Select(dr => dr.Field<string>("columnName")).ToList();
}
return result;
}
This would do as it is (if I didn't do any typos...)
private void LoadList()
{
List<string> tagsList = new List<string>();
using (IDbConnection connection = new SqlConnection(Properties.Settings.Default.DBConnectionString))
{
connection.Open();
using (IDbCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT TAGCOLUMN FROM TAGSTABLE";
using (IDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
if (!reader.IsDBNull(0))
tagsList.Add(reader.GetString(0));
}
reader.Close();
}
}
connection.Close();
}
}
EDIT:
Of course you have to change the select statement to the correct one from your database.
I just used a pseudo one to show you what to put there.

Categories