How to for each a dataset for each button? - c#

What is the syntax for iterating through a column and changing the values to each button as it iterates?
Example : I have an SQL table with a column named OK with values (0 or 1) and 20 buttons on a form, each button corresponds to a row (button 1 to row 1, button 2 to row 2...etc). I want to iterate through all 20 rows in my dataset and for each row to assign 0 or 1 to its corresponding button (as in button text)
EDIT : I didnt try anything yet cause i dont know exactly how, i know you can iterate through the rows with
Foreach (DataRow drow in table.Rows)
{
foreach(Button X in this.Controls
{
// It was my idea but it clearly doesnt work
}
}

//Sample for MySqlDB
using MySql;
using MySql.Data;
using MySql.Data.MySqlClient;
private List<string> NumberfromDb = new List<string>();
private int SingleValue = -1;
string QueryGetListUsers = "Select <tablename>.<Columname> From <tablename>;";
cmd = new MySqlCommand(Query, m_mySqlConnection);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
SingleValue = rdr.GetInt32("OK").ToString();
NumberfromDb.Items.Add(SingleValue);
}
Now you have the Value in the List Just pass it in the "For" loop and assign it to the Button
eg:
btn1.Text = NumberfromDb[i].ToString();

Related

Trying to delete selected row from datagridview but it is deleting multiple rows

It is a simple question, but since I am new to C#, I am not sure how to solve this.
Basically, I have a datagridview that displays records from MySQL table. I have a delete button, which by clicking performs the sql query, which is working fine, and is also meant to then delete the selected row from datgridview. But what actually happening, is it deletes multiple rows even when only one row is selected.
Here is the query:
private void delete_btn_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
string constring = #"server = localhost; user id = root; password = pass; persistsecurityinfo = false; database = mapping; allowuservariables = false";
using (MySqlConnection con = new MySqlConnection(constring))
{
using (MySqlCommand cmd = new MySqlCommand("UPDATE deletion SET date_time = UTC_TIMESTAMP() where product_id =" + proid_txtbx.Text, con))
{
cmd.Parameters.AddWithValue("#product_id", row.Cells["product_id"].Value);
cmd.Parameters.AddWithValue("#product_name", row.Cells["product_name"].Value);
cmd.Parameters.AddWithValue("#category_id", row.Cells["category_id"].Value);
cmd.Parameters.AddWithValue("#date_time", row.Cells["date_time"].Value);
con.Open();
cmd.ExecuteNonQuery();
}
foreach(DataGridViewRow item in this.dataGridView1.SelectedRows)
{
dataGridView1.Rows.RemoveAt(this.dataGridView1.SelectedRows[0].Index);
}
}
}
Screenshots:
Row 6 should be deleted:
Other Rows are deleted when I click Delete button
I think your problem is with your foreach loop. You are looping through all your rows with dataGridView1.Rows. Tr dataGridView1.SelectedRows instead:
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
if (!row.IsNewRow) dataGridView1.Rows.Remove(row);
You can use:
private void delete_btn_Click(object sender, EventArgs e)
{
//Works even when whole row is selected.
int rowIndex = datagridview.CurrentCell.RowIndex;
//You can also then easily get column names / values on that selected row
string product_id = datagridview.Rows[rowIndex].Cells["Column Name Here"].Value.ToString();
//Do additional logic
//Remove from datagridview.
datagridview.Rows.RemoveAt(rowIndex);
}
How about creating new command, somethnig like...
DELETE FROM YourTable WHERE product_id = ?
After that you can get value of selected item index:
int product_id = Convert.ToInt32(DataGridView1.SelectedRows[0].Cells[0].Value)
And at the end run the command and pass it the product_id int you got from command. I think it should work without problems...

How to retrieve data from database to CheckedListBox and set the items as checked?

I am new in WPF. I am trying to load the values from database to fill in CheckedListBox. Based on a condition, some items must be set to checked while loading in checkedlistbox.
How to do this? I have tried the code below, items are loaded in CheckedListBox, but are not checked.
Below is values loaded to checked listbox
public void fillcheck()
{
con = new SqlConnection(connectionstring);
con.Open();
string comboquery = "SELECT [Machine] FROM Department Where active='True'";
SqlCommand cmd = new SqlCommand(comboquery, con);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string fil1 = rdr.GetString(0);
Checkedlistbox1.Items.Add(fil1);
}
rdr.Close();
}
int departmentID=60//for just refer
Object[] jobs = CheckedlistBox1.Items.Cast<Object>().ToArray();
foreach (Object obj in jobs)
{
string query = "SELECT [Machine] FROM Department Where ID='" + departmentID+ "'";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataReader rdr = cmd.ExecuteReader();
while(rdr.Read())
{
string mac = rdr.GetString(0);//Here i get two values(XRAY,CT)but finally shown CT only be checked,so how to do both checked
if (mac == obj.ToString())
{
int indexx = CheckedlistBox1.Items.IndexOf(mac);
if (indexx >= 0)
{
CheckedlistBox1.SetItemChecked(indexx, true);
}
}
}
rdr.Close();
}
You need to transfer your SqlDataReader rdr content to a DataTable. That will help you get a DataTable object containing multiple rows like you have mentioned.
Now for the next step, you can apply a foreach on that DataTable object to iterate over all its rows like this :
foreach(DataRow dr in dt.Rows)
{
if(yourCondition)
{
//set isChecked = true for the checkbox.
}
}
UPDATE :
Try modifying your while loop like this :
while (rdr.Read())
{
string mac = rdr.GetString(0);
ListItem li = new ListItem();
li.Value = "yourBindedValue";// some value from database column
li.Text = "yourBindedText";// use mac if its text.
int index = Checkedlistbox1.Items.IndexOf(li);
if (index >= 0)
{
Checkedlistbox1.SetItemChecked(index, true);
}
}
I have tested this and it works. You just have to pass the Text and Value of the CheckBoxListItem that you are trying to find in the li object and you can get the index if it exists. Make sure you pass both the attributes.
You should have used code-
foreach (int indexChecked in chlstBox.Items)
instead of
foreach (int indexChecked in chlstBox.CheckedIndices)
At start you have 0 selected items and thats why your outer for loop is not working..
EDIT-
Basic Logic is also incorrect.
You should loop through dataset, find the string in checkboxlist and then check it. So, outer foreach loop is not required. Also, make sure that you are using correct checkboxlist variable. In for loop you are using chlstBox
and while searching you are using Checkedlistbox1 ....

Retrieved row values from query to textboxes

How can I put the values retrieved from a query that contains ONE COLUMN and MULTIPLE ROWS to textboxes. What i mean is txtBox1 will have the value of the first row, txtBox2 will have the value of the second row and so on. What I know is how to retrieve values of each column but not rows.
Perhaps:
List<TextBox> allTextBoxes = this.Controls.OfType<TextBox>().ToList();
int current = -1;
using (var con = new MySqlConnection(Properties.Settings.Default.ConnectionString))
{
using (var cmd = new MySqlCommand("SELECT ColumnName FROM dbo.TableName", con))
{
con.Open();
using (var rd = cmd.ExecuteReader())
{
while (rd.Read() && ++current < allTextBoxes.Count)
{
allTextBoxes[current].Text = rd.GetString(0);
}
}
}
}
replace this.Controls with the container control that contains all of your TextBoxes.

Unable to get dropdown selected value

I have a gridview that is populated with a dropdown list on each row. The DDL is populated with a number from 1 - how ever many rows there are.
I have a save button to save the value of each DDL for each row using a simple loop but the problem is that the dropdown never returns the selected value, it seems to return something like the row index of the gridview + 1.
This is an example of how I select the values in the rows:
3
7
4
6
5
2
1
When I do the same, this is how they will save:
2
3
4
5
6
7
1
This is my code from the save, just to let you know I have tried selectedvalue, selectedindex, selecteditem and text, they all do the same.
//save the data
foreach (GridViewRow r in gvOrder.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
//get the details from the grid
Label lblED = r.FindControl("lblED") as Label;
DropDownList ddl = r.FindControl("ddlNewO") as DropDownList;
TextBox txt = r.FindControl("txtNewT") as TextBox;
Label ID = r.FindControl("lblID") as Label;
int Order = Convert.ToInt16(ddl.SelectedValue);
string Text = "";
if (txt.Text != "")
{
Text = txt.Text;
}
//save each row to the db
try
{
SqlConnection dbConnection = new SqlConnection();
dbConnection.ConnectionString = GetConnection.GetConnectionString();
SqlCommand dbCommand = new SqlCommand("PL_UserColumns_Save", dbConnection);
dbCommand.CommandType = CommandType.StoredProcedure;
dbCommand.Parameters.Add("#PageID", SqlDbType.Int).Value = Convert.ToInt16(constPageID);
dbCommand.Parameters.Add("#UserID", SqlDbType.Int).Value = Convert.ToInt16(strUserID);
dbCommand.Parameters.Add("#Order", SqlDbType.Int).Value = Convert.ToInt16(Order);
dbCommand.Parameters.Add("#ColumnID", SqlDbType.Int).Value = Convert.ToInt16(ID.Text);
dbCommand.Parameters.Add("#ED", SqlDbType.Int).Value = Convert.ToInt16(lblED.Text);
dbCommand.Parameters.Add("#Text", SqlDbType.NVarChar).Value = "'" + Text + "'";
dbConnection.Open();
dbCommand.ExecuteNonQuery();
dbConnection.Close();
}
catch (SqlException ex)
{
ExceptionHandling.SQLException(ex, constPageID, constIsSiteSpecific);
}
}
}
to get the DropDownList selected value you have to use this:
ddl.SelectedItem.Value
You can check Request.Form to get the posted values. Assuming that your drop-down names will increase with each row e.g. ddlNew0, ddlNew1, etc., then you can do this
var value = Request.Form["ddlNew" + rowIndex];
I would do it in two possible ways:
Add a bit of JavaScript to populate a hidden field and then grab and separate the values in the back-end
Add auto-postback on dropdowns and an onClick method. Also pass the item id as argument. Then do the saving bit in the onclick method.
I would prefer the second one.

Efficient way to retrieve multiple values from the same column

I want to set some buttons text (content) with values I retrieve from a mysql.
till now I always did it like this:
if (rdr.Read())
{
Item1.Visibility = Visibility.Visible;
Item1txt.Text = rdr.GetString("item_name");
}
if (rdr.Read())
{
Item2.Visibility = Visibility.Visible;
Item2txt.Text = rdr.GetString("item_name");
}
if (rdr.Read())
{
Item3.Visibility = Visibility.Visible;
Item3txt.Text = rdr.GetString("item_name");
}
This way works fine because I retrieve the right values in each button, but it makes the readability horrible..
When I started this project I had zero knowledge of C# so I tried some things like:
while (rdr.Read())
{
Item4.Visibility = Visibility.Visible;
Item4txt.Text = rdr.GetString("item_name");
Item5.Visibility = Visibility.Visible;
Item5txt.Text = rdr.GetString("item_name");
}
But this gave me the same value retrieved from my database in my buttons..
example:
button 1: test1 | button 2: test1 | button 3: test1.. etc..
what i need:
button 1: test1 | button2: test2 | button 3: test3.. etc..
Now my knowledge of C# is getting better every day so I want to learn some new things.
Right now I'm trying to use the foreach loop but I have a feeling I'm missing something:
using (MySqlConnection conn = new MySqlConnection(_CS))
{
conn.Open();
string cmd = "SELECT * FROM ordertopos LIMIT 10";
MySqlCommand custid = new MySqlCommand(cmd, conn);
using (MySqlDataReader rdr = custid.ExecuteReader())
{
System.Data.DataTable dt = new System.Data.DataTable();
dt.Load(rdr);
foreach (System.Data.DataRow row in dt.Rows)
{
Orderl1.Text = row["customerid"].ToString();
}
}
}
Essentially I want to know how I can set the content of my buttons, retrieved from mysql, in a more efficient en easier to maintain code..
I'm fairly new with foreach, so please be specific.
i would recommend to do it in several step's for a better reusability
Step 1
List<string> myItems;
using (MySqlConnection conn = new MySqlConnection(_CS))
{
conn.Open();
string cmd = "SELECT * FROM ordertopos LIMIT 10";
MySqlCommand custid = new MySqlCommand(cmd, conn);
using (MySqlDataReader rdr = custid.ExecuteReader())
{
myItems= new List<string>();
while (rdr.Read())
{
myItems.Add(rdr.GetString("item_name"));
}
}
}
Step 2
modified Olivier Jacot-Descombe version
for(int i =0; i< myItems.count; i++) {
Button btn = FindChild<Button>(this, "Item" + i); //"this" will be the control which contains your button's
TextBlock tb = FindChild<TextBlock>(btn, "Item" + i + "txt");
btn.Visibility = Visibility.Visible;
tb.Text =myItems[i];
i++;
}
If you want to scale your problem in order to use loops than you need to have a List or an Array that contains objects for which you want to set values of properties. In your particular case, put your Orders in a List<Order> and then you could use something like this:
int count = 0;
foreach (System.Data.DataRow row in dt.Rows)
{
if(count<orders.Count)
orders[count++].Text = row["customerid"].ToString();
}
You need to traverse through your Items to set respective values. As DJ Kraze suggested, you are just overwriting the same control. And it will have the last accessed value (as it won't be overwritten once loop has ended).
You you just need to have somehow reference to your target controls, or if you are creating controls on the fly, than you can simply pass reference of newly created control every time you access a row from database.
You can access controls by their name instead of their member variable by using the FindChild method found here: WPF ways to find controls.
int i = 1;
while (rdr.Read()) {
Button btn = FindChild<Button>(this, "Item" + i);
TextBlock tb = FindChild<TextBlock>(btn, "Item" + i + "txt");
btn.Visibility = Visibility.Visible;
tb.Text = rdr.GetString("item_name");
i++;
}
This enables you to loop through them by using a counter (i).

Categories