Single datagridview row updating - c#

Could you help with such problem:
I have two forms, datagridview and SQL database.
On Load event of my first form I'm select some data from my SQL database by using stored procedure(select query).
SqlConnection con = new SqlConnection(constr);
SqlCommand cmd = new SqlCommand("PROC001", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
datagridview.DataSource = dt;
After that, I can filter or sort my datagridview by using dt.DefaultView.Filter = .... and display in my grid only filtered rows.
On CellMouseDoubleClick event my second Form2 appearing. In this form I update some value in database by clicking on Button1 and also after that I want to update my selected datagridview row. My quetions are:
1) How can I update only selected row in datagridview and do not execute stored procedure for all datagridview filling again.
2) My datagridview is already filtered, so if I execute procedure again, my filter has been disapeared. How can I avoid of this?
3) On Form2 I'm updating some database value, that is not included in my "select query" as selected field, but this value is affected on this query. Example:
SELECT Name, SecondName FROM tUsers
WHERE id = (SELECT DISTINCT id FROM tProcedures WHERE Code = 'First')
In my datagridview I can see Name and SecondName, but in Form2 I'm updating Code in tProcedures database table. So after updating I want to see my new data in datagridview, only in selected row and with current filter. I don't want to SELECT all data again to datagridview and broke my filter.
Is it possible to update single row? Could you provide some examples?

Because the DataGridView is using DataBinding, you have to update the underlying data source, in this case the DataTable. See How to: Edit Rows in a DataTable for how to do that.
For the filter issue, you would want to save and restore the filter:
var filter = dt.DefaultView.RowFilter;
UpdateData();
dt.DefaultView.RowFilter = filter;

Related

C# Updating a DataGridView/DataSource from MySQL

I'm writing a program that updates user accounts on a MySQL database. The program is going to be used on multiple computers at once.
Currently I load the MySQL data into a DGV by this and refresh in a similar way;
mySqlDataAdapter = new MySqlDataAdapter("SELECT * FROM a_Users;", connection); // Query the database
DataSet DS = new DataSet(); // Create new DataSet
mySqlDataAdapter.Fill(DS); // Fill the Dataset with the information gathered above
dataGridView1.DataSource = DS.Tables[0]; // Set the dgv source to the newly created DataSet
and when editing I get the DGV row to a DataRow, and then update the DGV by changing the DataRow like this (from another form);
DataRow dr = (dataGridView1.Rows[SelectedRow].DataBoundItem as DataRowView).Row; // Get the selected row to a new DataRow
dr["Phone Number"] = PhoneNumber_tb.Text;
My problem is, I want to update the DGV with any new/modified rows from the MySQL database every xx seconds, and if modifying a row when this happens the DataRow is then Invalid as the above code re-makes the whole structure.
Is there a way to update the DGV or DGV DataSource and maintain the ability to use the DataRow I pulled for editing?
How can I update the Datasource with any changes from the MySQL database.
I have tried BindingSource and a whole bunch of other things I have googled.
I could find UserID in the DGV then update the row that way, if no answer is found here.
Currently when editing a user, if the DGV refreshes with the SQL Database my edit form will not update the DGV as the DataRow no longer exists where it was.
This is what I am using, works nicely.
Only gets the rows that have been updated since we last checked. Still using the example in the question to retrieve the Database initially
mySqlDataAdapter = new MySqlDataAdapter("SELECT * FROM a_Users WHERE DTGModified > " + LastUpdated.ToString() + ";", connection); // Query the database
DataTable DT = new DataTable(); // Create new DataSet
mySqlDataAdapter.Fill(DT); // Fill the Dataset with the information gathered above
LastUpdated = DateTime.Now.ToString("yyyyMMddHHmmss"); // Save the time we retrieved the database
foreach (DataRow dr in (dataGridView1.DataSource as DataTable).Rows)
{
foreach(DataRow DTdr in DT.Rows)
{
if (dr["ID"].ToString() != DTdr["ID"].ToString()) continue;
dr.ItemArray = DTdr.ItemArray;
}
}

Alternative Ways In Adding New Rows in Datasource Data Grid View

I'm creating a project in C# windows form. What I'm trying to do is add new rows in the datasource data grid view. But the problem is, the error says that adding new rows can't add programmatically in the datasource data grid.
Here's my method in fetching the data and transfer it in the data grid view.
public DataTable GetData(ClassName classVar){
SqlCommand cmd = new SqlCommand();
cmd.Connection = ...; // My connection string
cmd.CommandType = CommandType.Text;
cmd.CommandText = ...; // My Query
DataTable table = new DataTable();
table = ...ExeReader(cmd);
return table;
}
The Codes inside my form
DataTable getDataTable;
getDataTable = ClassQuery.GetData(classVar);
dgv_details.DataSource = getDataTable;
And this is my add button
dgv_details.Rows.Add(txtBox1.Text,txtBox2.Text);
What are the alternative ways in adding data inside the datasourced datagridview?
Thanks in advance.
Try the below code. First add row to datatable and then bind that table to datagridview.
DataRow dr = datatable1.NewRow();
dr[0] = "HAI"; // add data in first column of row
datatable1.Rows.InsertAt(dr, 0); // insert new row at position zero
datatable1.Rows.Add(dr); // addnew row at last

How to Populate the unbounded datagridview from SQL Server database in C#?

In My Project I'm Using Unbounded datagridview with 33 columns for storing the user data in database and I need to populate the datagridview after each and every Insert, Update and Delete.
My Problem is while populating the datagridview with sql server query it shows the column header repeated with data.
my code is given below :
Private Void PopulateGrid()
{
cs.open();
sqladpter da= new sqlcommand("Select * from Customer",cs);
DataTable dt =new datatable();
da.fill(dt);
datagridview.datasource=dt;
datagridview.Refresh();
}
I'll Call This method at the End Of each and every Insert, Update and Delete.
How about Using something simple like datasource and you can have all your CRUD operations
http://msdn.microsoft.com/en-CA/library/dz12d98w(v=vs.100).aspx
try setting DataSource = null before setting new DataSource
datagridview.DataSource = null;
datagridview.DataSource = dt;

How to replace a DataBase Table by a DataTable

I am trying to replace a Table (FooTable) in my DataSource (an SQL CE Database) by a DataTable (which bind to a DataGrid). The reason I want to do this is: after I populate from a Database to a DataSet (which show all the rows on the DataGrid), I might edit, delete, and add multiple rows to the DataTable. Instead of updating my changes to DataSource (SQL CE) each time I modified the DataTable, I want to do it collectively at the end of the session.
My approach is straight-forward:
`DELETE` all data from my DataSource table (FooTable) (I'm using **SQL CE**, so `TRUNCATE` is not available)
INSERT the `DataTable's` data in to the emptied DataSource Table
Following is my C# code
/* Truncate the DataSource Table */
SqlCeCommand delCmd = new SqlCeCommand("DELETE FROM FooTable", conn)
conn.Open();
delCmd.ExecuteNonQuery();
conn.Close();
/* Insert DataTable into an empty DataSource Table */
string ins = #"INSERT INTO FooTable (FooName) values (#fooName)";
SqlCeCommand cmd = new SqlCeCommand(ins, conn);
da.InsertCommand = cmd;
da.Update(ds, "FooTable");
The codes work if I add or delete rows on the DataTable, but when I edit a specific row on the DataTable and Insert the table to my DataSource, I get the following error
"Update requires a valid UpdateCommand when passed DataRow collection with modified rows."
I do not understand why I get this error. I have already empty all rows in my DataSource table and my DataSource shouldn't not know there are modified rows but insert all DataTable Rows as new rows.
Or, is there a simple way to "REPLACE" a DataSource table by a DataTable?
[EDITED]
I tried setting the RowState manually like below code
foreach (DataRow row in dt.Rows)
{
row.RowState = DataRowState.Added;
}
but RowState is only read only and cannot be written.
[EDITED - 2nd]
I tried setting it using SetAdded()
foreach (DataRow row in dt.Rows)
{
row.SetAdded();
}
Then I get the following error:
"SetAdded and SetModified can only be called on DataRows with Unchanged DataRowState."
Still not manage to get it to work...
[EDITED - 3rd]
So finally get it to work with the following code:
using (SqlCeCommand insCmd = new SqlCeCommand(#"INSERT INTO FooTable (FooName) VALUES (#fooName)", conn))
{
insCmd.Parameters.Add("#fooName", SqlDbType.NVarChar, 10, "FooName");
dt.AcceptChanges();
foreach (DataRow row in dt.Rows)
{
row.SetAdded();
}
da.InsertCommand = insCmd;
da.Update(ds, "FooTable");
}
The DataTable tracks RowStates internally.
When you modify an existing row, its RowState becomes Modified, so the DataAdapter tries to run an UPDATE command.
You need to call the SetAdded() method on the modified rows to set their RowStates to Added rather than Modified.

Inserting just a new record using DataSet (.net c# ado.net )

I've a form containing more than 200 text boxes in .NET desktop application. I want to insert them into their respective 4 tables of Database. Now how should I go about it using Dataset & DataAdapter to do this?
I mean usually this will be the flow:
Populate the DataSet using DataAdapter.Fill(Dataset,"DataTable");
manipuate the data of DataSet
DataAdapter.Update(Dataset,"DataTable") updates the content back to Database.
Code:http://dev.mysql.com/doc/refman/5.1/en/connector-net-tutorials-intro.html#connector-net-tutorials-data-adapter
But here I just want to insert a new record in 3 different tables.
I think the way is to
Programmatically Create A dataset with 3 Datatables.
Bind 200 Textboxes to respective columns of these Datatabes
dataAdapter.Update(dataSet, dataTable.TableName);
Am I right?
How does dataAdapter.Update(dataSet, dataTable.TableName); work? Because, my each dataTable will have only one record. (the new record that is to be inserted. binded with those 200 TextBoxes of the form) where as the Table of the Database will have thousands of records. If I do dataAdapter.Update(dataSet, dataTable.TableName); will it delete all the rest of the records and insert this one alone?
I just want to insert a new record (without fetching other 1000s of records into my Dataset) into Database.Table using Dataset.
Each row has a RowState Property, this will be used by the dataAdapter. So if your dataset has only one new row, the row state will be DataRowState.Added. The DataAdapter will insert the row and change the row state to DataRowState.Unchanged. All other rows in the database will be unchanged.
IDbTransaction dbTransaction = dbConnection.BeginTransaction();
try
{
foreach (DataTable dataTable in dataSet.Tables)
{
string sql = "SELECT * FROM " + dataTable.TableName + " WHERE 0 = 1";
SqlDataAdapter dataAdapter = new SqlDataAdapter (sql, dbConnection);
dataAdapter.Update(dataSet, dataTable.TableName);
}
}
catch
{
dbTransaction.Rollback();
throw;
}
dbTransaction.Commit();
Remark: Will not work if there are constraints in the database defined.
Simply make the SQL insert commands and execute them:
string cmd="insert into myTable(column1, column2, etc) values (#text1,#text2, etc)";
SqlCommand sqlcmd=new SqlCommand(cmd,mySqlConnection);
sqlcmd.Parameters.Add("#text1",SqlDbType.NChar,textbox1.Text);
sqlcmd.Parameters.Add("#text2",SqlDbType.NChar,textbox2.Text);
sqlcmd.ExecuteNonQuery();

Categories