Error adding from database to dropdownlist - c#

I have a panel that is visible only when the Edit button from GridView is clicked.
In that panel is a form with a DropDownList and a TextBox where you can write a number and add it to a ListBox.
After all the numbers wanted are added to the ListBox when I click the button Finalize is adding to the database the data. In Gridview I have the name concatenate from database , because I have Lastname and Firstname separately.
To be more easy I chose to add from database in DropDownList when I click on Edit button with the specific ID.
When Edit button is clicked this error is showing:
Operation is not valid due to the current state of the object.
In the line where I add in DropDownList. I verified the names of my database, of my table , all and is correct. I even tried only with firstname , not concatenate and it does the same error. I don't know what is wrong. I hope you can help me. This is the code where the error appears.
protected void btnEditSO_Click(object sender, EventArgs e)
{
panelSO.Visible = true;
btnFinalizeSO.Text = " Update ";
Button but = (Button)sender;
GridViewRow grid = (GridViewRow)but.NamingContainer;
string select_sql_SOddl = "SELECT ID, (LASTNAMER | | ' ' | | FIRSTNAMER ) AS REFERENTNAME FROM REFERENT_SHIPPING WHERE ID=" + grid.Cells[14].Text;
using (OracleConnection con = new OracleConnection(ConfigurationManager.ConnectionStrings["DBCS"].ToString()))
{
con.Open();
OracleCommand cmd1 = new OracleCommand(select_sql_SOddl, con);
OracleDataReader dr1 = cmd1.ExecuteReader();
while (dr1.Read())
{
ddlReferentShip.Items.Add(dr[0].ToString());
// ddlReferentShip.Items.Add(dr["REFERENTNAME"].ToString());
// ddlReferentShip.DataSource = dr1;
// ddlReferentShip.DataTextField = dr1["REFERENTNAME"].ToString();
// ddlReferentShip.DataValueField = dr1["ID"].ToString();
// ddlReferentShip.DataBind();
}
}
}

You are checking dr1.Read()
and reading dr[0].Tostring()
Also try to clear the list before adding the data. Then the index should be 1 if you need to show the name
it should be
while (dr1.Read())
{
ddlReferentShip.Items.Add(dr1[1].ToString());
}
I guess ID is numeric in query you are passing as .Text
try this
string select_sql_SOddl = "SELECT ID, (LASTNAMER | | ' ' | | FIRSTNAMER ) AS REFERENTNAME
FROM REFERENT_SHIPPING WHERE ID=" + Convert.ToInt32(grid.Cells[14].Text);
also all ways try to use parameterized query to avoide SQL INJECTION

Why you set ddl item from dr when you have dr1 as datareader.
Maybe you can try this:
protected void btnEditSO_Click(object sender, EventArgs e)
{
panelSO.Visible = true;
btnFinalizeSO.Text = " Update ";
Button but = (Button)sender;
GridViewRow grid = (GridViewRow)but.NamingContainer;
string select_sql_SOddl = "SELECT ID, (LASTNAMER | | ' ' | | FIRSTNAMER ) AS REFERENTNAME FROM REFERENT_SHIPPING WHERE ID=" + grid.Cells[14].Text;
using (OracleConnection con = new OracleConnection(ConfigurationManager.ConnectionStrings["DBCS"].ToString()))
{
con.Open();
OracleCommand cmd = new OracleCommand(select_sql_SO, con);
OracleCommand cmd1 = new OracleCommand(select_sql_SOddl, con);
OracleDataReader dr = cmd.ExecuteReader();
OracleDataReader dr1 = cmd1.ExecuteReader();
int i=0;
while (dr1.Read())
{
ddlReferentShip.Items.Add(dr1[1].ToString());
i++;
// ddlReferentShip.Items.Add(dr["REFERENTNAME"].ToString());
// ddlReferentShip.DataSource = dr1;
// ddlReferentShip.DataTextField = dr1["REFERENTNAME"].ToString();
// ddlReferentShip.DataValueField = dr1["ID"].ToString();
// ddlReferentShip.DataBind();
}
}
}

Related

How to search with radio Button in c#

Table Form
I'm trying to filter this table with RadioButton when DateDePublication is Checked and the value of the search text equals for example 2000 table should return all books who have DateDePublication equals to 2000
this is Search Button code :
private void RechBtn_Click(object sender, EventArgs e)
{
dataGridView1.DataSource = repository.GetAllLivres(rechtext.Text);
}
and search method code to return all books :
public List<Livre> FilterDateDePublication(string date)
{
using (var connection = factory.CreateConnection())
{
var livres = new List<Livre>();
connection.ConnectionString = connectionString;
connection.Open();
var command = factory.CreateCommand();
command.Connection = connection;
command.CommandText = "select * from livre where date_publication like '%" + date + "%'";
using (DbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Livre l = new Livre();
l.Isbn = reader["isbn"].ToString();
l.Titre = reader["titre"].ToString();
l.DatePublication = DateTime.Parse(reader["date_publication"].ToString());
l.NombrePage = Int32.Parse(reader["nombre_page"].ToString());
l.Couverture = reader["couverture"].ToString();
l.Prix = Double.Parse(reader["nombre_page"].ToString());
l.QuantiteDisponible = Int32.Parse(reader["quantite_disponible"].ToString());
}
}
return livres;
}
your function GetAllLivres just looks for books with a specifc string in their title.
command.CommandText = "select * from livre where titre like '%" + mc + "%'";
You should change that to search on the pub date. Can says how that should look because we dont know your database scheme.
By the way , do not build SQL like that, its a huge security hole. Use parametrized queries
I know i have 4 radio buttons when one of them is checked Search function should look up by each of radio button.
Well again not seeing the UI its hard to say but my guess is you have something like this
|-search by: --------| <<< group box
| ( ) Author | << radio buttons
| ( ) title |
| (*) Year |
----------------------
Search for :_________________: <<== text box
[Start Search] <<== button
I hope so.
So do this
if(radioYear.Checked){
FilterDateDePublication(searchText.Text);
}
else if(radioAuthor.Checked)
.......
Note that the date the user enters might not match the format of the date in the database, in that case you need to do some massaging
I would however refactor your code, you have surely noticed that 90% of your FilterDateDePublication is the same as the title one.
You should do
public List<Livre> ReadBooks(string query)
{
using (var connection = factory.CreateConnection())
{
var livres = new List<Livre>();
connection.ConnectionString = connectionString;
connection.Open();
var command = factory.CreateCommand();
command.Connection = connection;
command.CommandText = query;
using (DbDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Livre l = new Livre();
l.Isbn = reader["isbn"].ToString();
l.Titre = reader["titre"].ToString();
l.DatePublication = DateTime.Parse(reader["date_publication"].ToString());
l.NombrePage = Int32.Parse(reader["nombre_page"].ToString());
l.Couverture = reader["couverture"].ToString();
l.Prix = Double.Parse(reader["nombre_page"].ToString());
l.QuantiteDisponible = Int32.Parse(reader["quantite_disponible"].ToString());
}
}
return livres;
}
and then have
List<Livre> GetByDate(string date){
return GetBooks("select * from livre where date_publication like '%" + date + "%'";
}
even better would be to use sql parameters. I will update this answer later

Update DataGridView Checked Record to the Database

So I have this DataGridView on which there are two columns which I am retrieving from my SQL Server database. Now, in the second column, we have a bit field which shows as a CheckBox in my Windows Application designer. So, I want to, on CellContentClick event be able to update the value that just got deselected into my database. But seems like I am going nowhere.
Here is my code below:
private void gvTurnOffNotifications_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
foreach (DataGridViewRow row in gvTurnOffNotifications.Rows)
{
DataGridViewCheckBoxCell cell = row.Cells[1] as DataGridViewCheckBoxCell;
//We don't want a null exception!
if (cell.Value != null)
{
bool result = Convert.ToBoolean(row.Cells[1].Value);
if (result == true)
{
//It's checked!
btnUpdateTurnOff.Enabled = true;
myConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (mySQLConnection = new SqlConnection(myConnectionString))
{
int temp = 1;
bool change = false;
string procedureName = "update UsersNotified Set AllowNotification='" + change + "' where AllowNotification='" + false+ "'";
mySQLCommand = new SqlCommand(procedureName, mySQLConnection);
mySQLCommand.CommandType = CommandType.Text;
mySQLCommand.Connection = mySQLConnection;
mySQLCommand.Connection.Open();
mySQLCommand.ExecuteNonQuery();
}
}
}
}
}
And then when I click on my "Update" button, I want to send the updated griddata for storing in my database as below:
private void btnUpdateTurnOff_Click(object sender, EventArgs e)
{
myConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (mySQLConnection = new SqlConnection(myConnectionString))
{
mySQLDataAdapter = new SqlDataAdapter("spGetAllUpdatedNotifications", mySQLConnection);
mySQLDataAdapter.SelectCommand.CommandType = CommandType.StoredProcedure;
mySQLCommand.Connection = mySQLConnection;
mySQLCommand.Connection.Open();
DataSet ds = new DataSet();
mySQLDataAdapter.Fill(ds);
mySQLDataAdapter.UpdateCommand = mySQLCommand;
mySQLDataAdapter.Update(ds);
}
}
The spGetAllUpdatedNotifications object in my Update block is a stored procedure I am calling just to retrieve the records from the database so I can update them on the fly in my DataSet. Here is the definition below:
create proc spGetAllUpdatedNotifications
as
begin
SELECT UserName, AllowNotification FROM UsersNotified where AllowNotification=1
end
GO
For more context: When my form loads, I am selecting all the records from the database which have their AllowNotification field set to bit 1 (true in C#) and once a user unticks a specific user (in other words, that user would not be allowed to receive notifications anymore) and once I click on the Update button, it should set the property to false (bit 0 in the database).
Instead of updating the one record which I have deselected, it updates all of them. "All" in this case are the records which have AllowNotification=1. I only want to set AllowNotification=0 for the deselected/unchecked record only
Any suggestions on how I can go about achieving this?
I am not sure what logic makes you to loop thru all the rows of the DataGridView just to update one row in the database.
If you want to update AllowNotification value for the username for which checkbox is checked or unchecked the logic would be this.
Figure out the updated value of the checkbox which is clicked in the gridview.
Store the updated value (True or False) in a boolean variable.
Retrieve the corresponding username of from the other cell of the same row the gridview.
Execute update query with criteria "WHERE UserName = {userName}".
You need to write CellContentClick event of the DataGridView as following.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 1) //Assuming Checkbox is displayed in 2nd column.
{
this.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
var result = this.dataGridView1[e.ColumnIndex, e.RowIndex].Value;
var userName = this.dataGridView1[0, e.RowIndex].Value; //Assumin username is displayed in fist column
var connectionString = "Your Connection String";
//Set value of your own connection string above.
var sqlQuery = "UPDATE UsersNotified SET AllowNotification = #allowNotification WHERE UserName = #userName";
using (var connection = new SqlConnection(connectionString))
{
using (var command = new SqlCommand(sqlQuery, connection))
{
command.CommandType = CommandType.Text;
command.Parameters.Add("#allowNotification", SqlDbType.Bit).Value = result;
command.Parameters.Add("#UserName", SqlDbType.NVarChar).Value = userName;
connection.Open();
command.ExecuteNonQuery();
}
}
}
}
This should help you resolve your issue.
I have a partial solution (It doesn't work a 100% but at least its a step in the right direction):
private void gvTurnOffNotifications_SelectionChanged(object sender, EventArgs e)
{
if (gvTurnOffNotifications.SelectedCells.Count > 0)
{
int selectedrowindex = gvTurnOffNotifications.SelectedCells[0].RowIndex;
DataGridViewRow selectedRow = gvTurnOffNotifications.Rows[selectedrowindex];
getUserSelected = Convert.ToString(selectedRow.Cells["UserName"].Value);
MessageBox.Show(getUserSelected);
foreach (DataGridViewRow row in gvTurnOffNotifications.Rows)
{
DataGridViewCheckBoxCell cell = row.Cells[1] as DataGridViewCheckBoxCell;
//We don't want a null exception!
if (cell.Value != null)
{
//It's checked!
btnUpdateTurnOff.Enabled = true;
myConnectionString = ConfigurationManager.ConnectionStrings["FSK_ServiceMonitor_Users_Management.Properties.Settings.FSK_ServiceMonitorConnectionString"].ConnectionString;
using (mySQLConnection = new SqlConnection(myConnectionString))
{
bool change = false;
string procedureName = "update UsersNotified Set AllowNotification='" + change + "' where UserName='" + getUserSelected + "'";
//MessageBox.Show(cell.Value.ToString());
mySQLCommand = new SqlCommand(procedureName, mySQLConnection);
mySQLCommand.CommandType = CommandType.Text;
mySQLCommand.Connection = mySQLConnection;
mySQLCommand.Connection.Open();
mySQLCommand.ExecuteNonQuery();
}
}
}
}
}
Problem is that it just takes the first row without me having selected the row I want to deselect.

How to get the data when I select a datagridview cell or column

I have 2 datagridview controls in a Windows Forms application.
I would like to get the info of a person when I select first datagridview cell or row to next datagridview:
try
{
ConnectionStringSettings consettings = ConfigurationManager.ConnectionStrings["attendancemanagement"];
string connectionString = consettings.ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
con.Open();
adap3 = new SqlDataAdapter(#"SELECT Date,Attendance,Remarks FROM dailyattendance where employee_id='"+DailyGV.CurrentRow+"'", con);
ds3 = new DataSet();
adap3.Fill(ds3, "dailyattendance");
dataGridView1.DataSource = ds3.Tables[0];
}
Im trying the above code. But it's not working.
I'm not too sure what DailyGV.CurrentRow is but basically you can use the RowHeaderMouseClick...see MSDN documentation. To use it, hook an event handler to it when initializing the form components (you can use VS designer as well...
dataGridView1.RowHeaderMouseClick += dataGridView1_RowHeaderMouseClick;
void dataGridView1_RowHeaderMouseClick(
object sender, DataGridViewCellMouseEventArgs e)
{
}
this event handler will get fired everytime you select a row header in the DataGridView control which will pass information about the event through an instance of the DataGridViewCellMouseEventArgs class (see MSDN documentation). This argument has a RowIndex property that provides the index of the row clicked which you can use to retrieve the values of the cells in that row...including the person id (if provided)...for example...
void dataGridView1_RowHeaderMouseClick(
object sender, DataGridViewCellMouseEventArgs e)
{
string personId = dataGridView1.Rows[e.RowIndex].Cells["PersonId"].Value;
//TODO: implement your own query to retrieve data for that person id
}
notice that you need to provide a proper column name when access the cells collection indexer...Cells["columnName"]
I will not give any description about the solution because Leo and Arsalan Bhatti has already suggested the solution. I am just telling you how your code should looks like and how it should be written.
string connectionString = consettings.ConnectionString;
using (SqlConnection con = new SqlConnection(connectionString))
{
try
{
con.Open();
string empID = DailyGV.CurrentRow.Cells["employee_id"].Value.ToString();
SqlCommand Cmd = con.CreateCommand();
Cmd.CommandText = "SELECT Date,Attendance,Remarks FROM dailyattendance where employee_id=#employee_id";
Cmd.Parameters.Add("#employee_id", SqlDbType.Int).Value = Int32.Parse(empID);
adap3 = new SqlDataAdapter(Cmd);
DataTable dt = new DataTable();
adap3.Fill(dt);
dataGridView1.DataSource = dt;
con.Close();
}
catch
{}
}
try
{
cn.Open();
string query = "select employee_id,Employee_Name,Image_of_Employee from Employee_Details where employee_id='" + dataGridView1.SelectedCells[0].Value.ToString() + "'";
SqlCommand cmd = new SqlCommand(query, cn);
SqlDataReader sdr;
sdr = cmd.ExecuteReader();
if (sdr.Read())
{
string aa = (string)sdr["employee_id"];
string bb = (string)sdr["employee_name"];
txtEmployeeID.Text = aa.ToString();
txtnameofemployee.Text = bb.ToString();
byte[] img=(byte[])sdr["Image_of_employee"];
MemoryStream ms=new MemoryStream(img);
ms.Seek(0,SeekOrigin.Begin);
pictureBox1.Image=Image.FromStream(ms); cn.Close();
}
}
catch (Exception e1)
{
MessageBox.Show(e1.Message);
}
You are passing the current row's index as employee id in SELECT query. Pass employee id for the selected record. Then it will work fine.

Problems with displaying data in datagrid view column

I am using datagrid view in a windows form application. I have several data grids that display a date date column. When I display my data, the date shows correctly but is always followed by '00:00:00'. How can I change it to only display the date as 'dd/mm'yyyy'.
I build my datagrid as follows:
//Populate customers datagrid view
private void displayInGrid_Customers(string sqlcmd)
{
customersDataGridView.Rows.Clear();
connect.Open();
command.Connection = connect;
command.CommandText = sqlcmd;
reader = command.ExecuteReader();
while (reader.Read())
{
// add a row ( get index )
int arow = customersDataGridView.Rows.Add();
// datagridname.row[index].cells.value = reader[table].tostring()
customersDataGridView.Rows[arow].Cells[0].Value = reader["Customer_ID"].ToString();
customersDataGridView.Rows[arow].Cells[1].Value = reader["Forename"].ToString();
customersDataGridView.Rows[arow].Cells[2].Value = reader["Surname"].ToString();
customersDataGridView.Rows[arow].Cells[3].Value = reader["Address"].ToString();
customersDataGridView.Rows[arow].Cells[4].Value = reader["Town"].ToString();
customersDataGridView.Rows[arow].Cells[5].Value = reader["Postcode"].ToString();
customersDataGridView.Rows[arow].Cells[6].Value = reader["Date_Of_Birth"].ToString();
customersDataGridView.Rows[arow].Cells[7].Value = reader["Phone_Number"].ToString();
customersDataGridView.Rows[arow].Cells[8].Value = reader["Email"].ToString();
customersDataGridView.Rows[arow].Cells[9].Value = reader["Current_Rental"].ToString();
customersDataGridView.Sort(Surname, ListSortDirection.Ascending);
}
reader.Close();
connect.Close();
}
//Display all customers button
private void button_view_all_customers_Click(object sender, EventArgs e)
{
command.CommandText = "SELECT CUSTOMERS.Customer_ID, CUSTOMERS.Forename, CUSTOMERS.Surname, CUSTOMERS.Address, "
+ "CUSTOMERS.Town, CUSTOMERS.Postcode, CUSTOMERS.Date_Of_Birth, CUSTOMERS.Phone_Number, CUSTOMERS.Email, CUSTOMERS.Current_Rental "
+ "from CUSTOMERS LEFT JOIN STOCK ON CUSTOMERS.Current_Rental = STOCK.Product_ID";
string cmd = command.CommandText;
displayInGrid_Customers(cmd);
Also, I have another problem in a different datagrid. This one has a payment column and when I originally created the table in access, the data in the column was like '£4.99' and right justified as expected but when I display it, there is no '£' symbol and it is left justified.
Code for that datagrid is:
//Populate payments datagrid view
private void displayInGrid_Payments(string sqlcmd)
{
paymentsDataGridView.Rows.Clear();
connect.Open();
command.Connection = connect;
command.CommandText = sqlcmd;
reader = command.ExecuteReader();
while (reader.Read())
{
// add a row ( get index )
int arow = paymentsDataGridView.Rows.Add();
paymentsDataGridView.Rows[arow].Cells[0].Value = reader["Customer_ID"].ToString();
paymentsDataGridView.Rows[arow].Cells[1].Value = reader["Payment"].ToString();
paymentsDataGridView.Rows[arow].Cells[2].Value = reader["Payment_Date"].ToString();
}
reader.Close();
connect.Close();
}
//Display all payments
private void button_display_payments_Click(object sender, EventArgs e)
{
command.CommandText = "SELECT PAYMENTS.Customer_ID, PAYMENTS.Payment, PAYMENTS.Payment_Date "
+ "from PAYMENTS LEFT JOIN CUSTOMERS ON PAYMENTS.Customer_ID = CUSTOMERS.Customer_ID";
string cmd = command.CommandText;
displayInGrid_Payments(cmd);
}
For the first part try:
customersDataGridView.Rows[arow].Cells[6].Value = ((DateTime)reader["Date_Of_Birth"]).ToShortDateString()
And for the second part try:
paymentsDataGridView.Rows[arow].Cells[1].Value = reader["Payment"].ToString("C");
paymentsDataGridView.Rows[arow].Cells[1].Value = String.Format("{0:C}", decimal.Parse(reader["Payment"].ToString()));
If it still gives error, try changing decimal for double, although for money and currency I would avoid double because of rounding errors it could give.

How to delete from database selected item in ListView in C#

I am using Microsoft SQL Server and Visual Studio-C# 2010 Ultimate.
I have a ListView and some items in it. I want to delete an item when I selected it and I clicked the button but I could not write the SqlCommandtext and I could not find the select event for ListView.
Deleting selected data from database using listview c#
private void btnlvdeleterow_Click(object sender, EventArgs e)
{
foreach (int i in Listview2.SelectedIndices)
{
string test = Listview2.Items[i].Text;
Listview2.Items.Remove(Listview2.Items[i]);
SQLiteCommand conn = new SQLiteCommand();
conn.Connection = DbClass1.GetConnection();
string del = "delete from UserData where UserName='" + test + "'";
int result=dbclass1.ExecuteAndReturn(del);
}
}
There is a SelectedIndex property available with the ListView. When you click the button, pass this index and then your Sql query will be something like
delete from Products where ProductID = 'obj.ID' where obj is obtained from listView.SelectedIndex
protected void listview1_ItemDeleting(object sender, ListViewDeleteEventArgs e)
{
//This retrieves the selected row
ListViewItem item= listview1.Items [e.ItemIndex];
// Fetch the control for ProductId using findControl
int productId=int.Parse((item.Findcontrol("ProductID") as TextBox).Text);
//then use this column value in your sqlcommand
using( SqlCommand cmd = new SqlCommand
("delete from Products where ProductID=#ProductId", connection ))
{
command.Parameters.Add(new SqlParameter("ProductId", productId));
//Then execute the query
}
}
try
{
for (int j = 0; j <= listView2.Items.Count - 1; j++)
{
string test = listView2.SelectedItems[j].SubItems[1].Text;
string MyConnection2 = "datasource=localhost;port=3306;username=root;password=root";
string Query = "delete from TABLE_NAME where COL_NAME='" + test + "'";
MySqlConnection MyConn2 = new MySqlConnection(MyConnection2);
MySqlCommand MyCommand2 = new MySqlCommand(Query, MyConn2);
MySqlDataReader MyReader2;
MyConn2.Open();
MyReader2 = MyCommand2.ExecuteReader();
while (MyReader2.Read())
{
}
MyConn2.Close();
MessageBox.Show("Data Deleted");
// txtCustomerName.Text = test;
//listView2.Items.Remove(listView2.Items[i]);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
The Event you are looking for should be ListView.ItemSelectionChanged
where the eventArgs contains the selected Items

Categories