How to edit data in search result in c# - c#

I managed to create a code for my edit button and search button. My edit button is functional. It can edit my data in database, my search code is also functional. My problem is to edit data in search results. Like if i search "naruto", my datagridview will filter all the names that has "naruto" on the database. After i choose and doubleclick on the result, all data will reappear to my textbox. But when i edit that data, it doesn't work. Instead, the first data on my database is the one that is changing not the one that i choose. My edit code is working if i don't search any names and don't choose on the search result.
here's my codes. Please HELP...
private void JOGridView_DoubleClick(object sender, EventArgs e)
{
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter("Select * from JobOrder", con);
if (JOGridView.CurrentCell != null && JOGridView.CurrentCell.Value != null)
{
TBName.Text = JOGridView.SelectedRows[0].Cells[0].Value.ToString();
TBContact.Text = JOGridView.SelectedRows[0].Cells[1].Value.ToString();
CBStatus.Text = JOGridView.SelectedRows[0].Cells[2].Value.ToString();
TBModel.Text = JOGridView.SelectedRows[0].Cells[3].Value.ToString();
TBSerial.Text = JOGridView.SelectedRows[0].Cells[4].Value.ToString();
TBAccess.Text = JOGridView.SelectedRows[0].Cells[5].Value.ToString();
TBRB.Text = JOGridView.SelectedRows[0].Cells[6].Value.ToString();
TBRP.Text = JOGridView.SelectedRows[0].Cells[8].Value.ToString();
TBIT.Text = JOGridView.SelectedRows[0].Cells[10].Value.ToString();
CBRamarks.Text = JOGridView.SelectedRows[0].Cells[11].Value.ToString();
TBCharge.Text = JOGridView.SelectedRows[0].Cells[12].Value.ToString();
TBRELB.Text = JOGridView.SelectedRows[0].Cells[13].Value.ToString();
}
}
private void BTNEdit_Click(object sender, EventArgs e)
{
{
DialogResult dr;
dr = MessageBox.Show("Are you sure you want to Edit this record?", "Update Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dr == DialogResult.Yes)
{
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM JobOrder", con);
da.Fill(dt);
dt.Rows[JOGridView.CurrentRow.Index].BeginEdit();
dt.Rows[JOGridView.CurrentRow.Index][1] = TBName.Text;
dt.Rows[JOGridView.CurrentRow.Index][2] = TBContact.Text;
dt.Rows[JOGridView.CurrentRow.Index][3] = CBStatus.Text;
dt.Rows[JOGridView.CurrentRow.Index][4] = TBModel.Text;
dt.Rows[JOGridView.CurrentRow.Index][5] = TBSerial.Text;
dt.Rows[JOGridView.CurrentRow.Index][6] = TBAccess.Text;
dt.Rows[JOGridView.CurrentRow.Index][7] = TBRB.Text;
dt.Rows[JOGridView.CurrentRow.Index][8] = DTDR.Text;
dt.Rows[JOGridView.CurrentRow.Index][9] = TBRP.Text;
dt.Rows[JOGridView.CurrentRow.Index][10] = DTDF.Text;
dt.Rows[JOGridView.CurrentRow.Index][11] = TBIT.Text;
dt.Rows[JOGridView.CurrentRow.Index][12] = CBRamarks.Text;
dt.Rows[JOGridView.CurrentRow.Index][13] = TBCharge.Text;
dt.Rows[JOGridView.CurrentRow.Index][14] = TBRELB.Text;
dt.Rows[JOGridView.CurrentRow.Index][15] = DTDR.Text;
dt.Rows[JOGridView.CurrentRow.Index].EndEdit();
SqlCommandBuilder cb = new SqlCommandBuilder(da);
da.Update(dt);
displayrecords();
MessageBox.Show("Selected record has been Updated!", "Done Updating ", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
clearrecords();
}
}
private void TBSearch_KeyUp(object sender, KeyEventArgs e)
{
if (TBSearch.Text == " ")
{
}
else
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Select * from JobOrder where Name like ('" + TBSearch.Text + "%')";
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
JOGridView.DataSource = dt;
con.Close();
}

It's hard to be more specific without seeing more of your code, but the core problem is at least in part that you're not using an MVVM (model view viewmodel) or MVC style binding between the query results and the database query.
Here's why you're only updating the first row in the table rather than the selected row
//creates a new table not visible or linked anywhere
DataTable dt = new DataTable();
//gets every record in JobOrder
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM JobOrder", con);
//fills the DataTable dt with all records from JobOrder
da.Fill(dt);
//uses the current index from the items in JOGridView to select a row in the unconnected/unrelated DataTable dt
dt.Rows[JOGridView.CurrentRow.Index].BeginEdit();
dt.Rows[JOGridView.CurrentRow.Index][1] = TBName.Text;
If you want it to work as written, you'll need to use some value from JOGridView.CurrentRow and match it to a row in dt. Then you can build your update query aimed at the correct row.
Ideally instead, you'll re-write the application to use a proper MVVM style binding to do all of the connections for you automatically.

Related

Gridview wont add another row on button click, it only adds one row and it updates that row only, how to fix this?

So I have a dropdown list that is being populate from database, the goal is to get the selected values from the dropdown list and put in the gridview. The problem is it only adds one row and only updates that row when I try to select new values from the dropdownlist.
I have tried doing Datarow row = dt.newrow() but not luck
Back End code of button click
string CS = ConfigurationManager.ConnectionStrings["POS_SystemConnectionString2"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("SELECT * FROM Product_Details WHERE Model = '" + ddlModel.SelectedItem.Text + "' AND Price = '" +ddlPrice.SelectedItem.Text + "'", con);
con.Open();
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
First image when I select values from dropdown list for first time
Second image is when I select new values from dropdown list but it updates previous table and does not add new row in gridview
On Add Button click you are retrieving new data from database and creating new datatable that's why you are loosing the previously selected data.
You need to maintain the previously retrieved data between two clicks on Add button.
You need to create a separate DataTable in aspx.cs and store it in the ViewState and add new row to that table on button click and re-bind it to the GridView.
You need to write following code to achieve this.
//This method will check if the table exist in the ViewState
//If table does not exist in ViewState, a new table will be created and stored in ViewState
private DataTable GetDataTable()
{
DataTable dt = ViewState["SelectedModels"] as DataTable;
if (dt == null)
{
dt = new DataTable();
dt.TableName = "ColorData";
dt.Columns.Add(new DataColumn("Model", typeof(string)));
dt.Columns.Add(new DataColumn("Price", typeof(string)));
ViewState["SelectedModels"] = dt;
}
return dt;
}
//This method will store DataTable to ViewState
private void SaveDataTable(DataTable dataTable)
{
ViewState["SelectedModels"] = dataTable;
}
//This method will get the data from the database, add it to the DataTable
//And it will re-bind the DataTable to the GridView and store the updated DataTable to ViewState
private void AddItemToList(string modelName, string price)
{
string CS = ConfigurationManager.ConnectionStrings["POS_SystemConnectionString2"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
using (SqlCommand cmd =
new SqlCommand("SELECT * FROM Product_Details WHERE Model = #modelName AND Price = #price", con))
{
var modelParameter = new SqlParameter();
modelParameter.ParameterName = "#modelName";
modelParameter.Value = modelName;
cmd.Parameters.Add(modelParameter);
var priceParameter = new SqlParameter();
priceParameter.ParameterName = "#price";
priceParameter.Value = price;
cmd.Parameters.Add(priceParameter);
con.Open();
using (var sqlReader = cmd.ExecuteReader())
{
var dataTable = GetDataTable();
while (sqlReader.Read())
{
var dataRow = dataTable.NewRow();
//Hear I assume that Product_Details table has Model and Price columns
//So that sqlReader["Model"] and sqlReader["Price"] will not have any issue.
dataRow["Model"] = sqlReader["Model"];
dataRow["Price"] = sqlReader["Price"];
dataTable.Rows.Add(dataRow);
}
SaveDataTable(dataTable);
GridView1.DataSource = dataTable;
GridView1.DataBind();
}
}
}
}
And now the Click Event Handler of the button should call the above method as following.
protected void bttnAdd_Click(object sender, EventArgs e)
{
AddItemToList(ddlModel.SelectedItem.Text, ddlPrice.SelectedItem.Text);
}
This should help you resolve your issue.

Textbox filter through SQL Datagridview - displaying too many columns (Duplicate Columns)

The search method is here:
private void textBox1_TextChanged(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=DESKTOP-HNR3NJB\\mysql;Initial Catalog=stock;Integrated Security=True");
SqlDataAdapter sda = new SqlDataAdapter("SELECT ProductName FROM [stock].[dbo].[Products]", con);
sda.Fill(dt);
dataGridView1.DataSource = dt;
dt.DefaultView.RowFilter = string.Format("ProductName LIKE '%{0}%'", textBox1.Text);
}
Now that does filter out the results in the table, but it adds columns like the picture below:
Search Results
Load data function (gets called as soon as the form is loaded:
public void LoadData()
{
SqlConnection con = new SqlConnection(#"Data Source=DESKTOP-HNR3NJB\mysql;Initial Catalog=stock;Integrated Security=True");
con.Open();
//reading data from sql
SqlDataAdapter sda = new SqlDataAdapter("SELECT * FROM [stock].[dbo].[Products]", con);
dt = new DataTable();
sda.Fill(dt);
dataGridView1.Rows.Clear();
foreach (DataRow item in dt.Rows)
{
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value = item["ProductID"].ToString();
dataGridView1.Rows[n].Cells[1].Value = item["ProductName"].ToString();
if ((bool)item["ProductStatus"])
{
dataGridView1.Rows[n].Cells[2].Value = "Active";
}
else
{
dataGridView1.Rows[n].Cells[2].Value = "Inactive";
}
dataGridView1.Rows[n].Cells[3].Value = item["Employee"].ToString();
dataGridView1.Rows[n].Cells[4].Value = item["CPU"].ToString();
dataGridView1.Rows[n].Cells[5].Value = item["RAM"].ToString();
dataGridView1.Rows[n].Cells[6].Value = item["SSD"].ToString();
dataGridView1.Rows[n].Cells[7].Value = item["HDD"].ToString();
dataGridView1.Rows[n].Cells[8].Value = item["WindowsVersion"].ToString();
dataGridView1.Rows[n].Cells[9].Value = item["Description"].ToString();
dataGridView1.Rows[n].Cells[10].Value = item["Type"].ToString();
}
con.Close();
}
Thanks
OK, so you're filling the datagridview elsewhere. You would just need to apply the rowfilter to the view to in the textbox_textchanged event
Where you're populating your current datagridview, ensure that you have your dt instantiated in a wider scope so that the textbox event can access it and then all you should have to do in your textchanged event is the following line:
dt.DefaultView.RowFilter = string.Format("ProductName LIKE '%{0}%'", textBox1.text);
This should then limit the rows to what is currently found. Here's an example of a demo database (you will have to change this to suit your needs)
DataTable dt; //declared outside a method so that multiple methods have access to it object.
private void Form1_Load(object sender, EventArgs e)
{
//Some other area where the datagridview is populated with more information
SqlConnection con = new SqlConnection(#"MyConnectionString");
con.Open();
SqlDataAdapter sda = new SqlDataAdapter("SELECT FirstName, LastName, Address, State FROM Employee", con);
dt = new DataTable();
sda.Fill(dt);
dataGridView1.DataSource = dt;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
//all that should be needed to filter the datagridview to your condition
dt.DefaultView.RowFilter = string.Format("FirstName LIKE '%{0}%'", textBox1.Text);
}
Of course, you really need to switch to using statements so that the objects used are disposed of properly but this is to show more that the basic reason your grid is doing this is that you are applying another datasource into the grid and it doesn't know that you still want all the information you had prior just limited to rows that match your filter.
EDIT - FOR CLARIFICATION
Let's do this. In your loaddata code, remark out the entire for each loop. Add the following lines
datagridview1.columns.clear();
datagridview1.datasoure = dt;
This will hide your pre-existing columns for now without you having to do it manually.
And should show the grid with all the information from the query.
Then in your textchanged event remark all your code and replace it with the line I showed above that uses the DefaultView of the datatable (dt)
That should get you up and running. Once that's done, we can make a change to the query that will allow you to show 'Active'/'InActive' instead of the checkbox for the bit field.

How to print selected row from DataGridView in C# with SQL

Using the following code the first row in SQL is printed only, How can I print selected row from DataGridView in C# with SQL:
public partial class PrintScreen : Form
{
SqlConnection con = new SqlConnection(#"Server = TEST;DataBase=Registration;Integrated Security=true;");
SqlDataAdapter da;
DataTable dt = new DataTable();
public PrintScreen()
{
InitializeComponent();
da = new SqlDataAdapter("select * from data_graduation", con);
da.Fill(dt);
this.dataGridView1.DataSource = dt;
}
private void Print_ys_ar_cert_Click(object sender, EventArgs e)
{
Print_ys_ar_cert frm = new Print_ys_ar_cert();
da = new SqlDataAdapter("select * from data_graduation where ID_gra = '" + dataGridView1.CurrentRow.Cells[0].Value.ToString() + "'", con);
da.Fill(frm.RegistrationDataSet1.data_graduation);
frm.reportViewer2.RefreshReport();
frm.Show();
}
}
Currently you are passing value of Cells[0] of first row of the grid, you need to pass value of selected row:
if(dataGridView1.SelectedRows.Count>0)
{
var selectedValue = dataGridView1.SelectedRows[0].Cells[0].ToString();
//rest of code
}
Since you have loaded the row from database once, you don't need to load it again from database, you can simply add it to the data table which is data source of the report this way:
var row = ((DataRowView)(dataGridView1.SelectedRows[0].DataBoundItem)).Row;
frm.RegistrationDataSet1.data_graduation.Rows.Add(row.ItemArray);
//rest of code

Add row from datagridview1 to datagridview2

I have two datagridviews in one from. I need to get data from database to datagridview1 (using Select *from database...) then I want to add data from datagriwview to datagridview2 using Selected Rows.
First I wanted to solve this problem to get Selected Row's ID, when I select row in datagridview it shows in datagridview2, but when I select another row, it is updating in datagridview, it does not add as new row. I tried several ways but did not solve this problem, Is there anyone help me to solve this problem? Thanks
private void dataGridView1_CellDoubleClick_1(object sender, DataGridViewCellEventArgs e)
{
int id = Convert.ToInt32
(dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["id"].Value);//3
try
{
MySqlConnection conn = new MySqlConnection(connection);
MySqlCommand command = start.CreateCommand();
command.CommandText = "SELECT id, muayine_adi, sabit_qiymet FROM tibbi_xidmetler WHERE id = '" + id.ToString() + "'";
conn.Open();
MySqlDataAdapter oxu = new MySqlDataAdapter(command);
DataTable dt = new DataTable();
oxu.Fill(dt);
dataGridView2.DataSource = dt;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Is quite simple the explanation: everytime that you make a double click to a datagridview1's cell you replace the old datatable with a new one. If you want append the result you can do something like this:
MySqlConnection conn = new MySqlConnection(connection);
MySqlCommand command = start.CreateCommand();
command.CommandText = "SELECT id, muayine_adi, sabit_qiymet FROM tibbi_xidmetler WHERE id = '" + id.ToString() + "'";
conn.Open();
MySqlDataAdapter oxu = new MySqlDataAdapter(command);
DataTable dt = new DataTable();
oxu.Fill(dt);
if(dataGridView2.DataSource != null) {
DataTable pr = dataGridView2.DataSource as DataTable;
pr.Merge(dt);
dataGridView2.DataSource = pr;
}
else
dataGridView2.DataSource = dt;
Since you have all information in datagridview1 you should just copy the contents of the selected row into a new row for datagridrow2.
The DataGridView is based on a DataSet which contains DataTables.
The DataTable contains rows.
You cannot move a row from one table to annother.
Instead you have to create a new row and insert into the DataTable of DataGridView2
private void dataGridView1_CellDoubleClick_1(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.CurrentRow.Cells["Id"].Value != null)
{
int Id = Convert.ToInt32(dataGridView1.CurrentRow.Cells["Id"].Value);
MySqlConnection start = new MySqlConnection(baglanti);
MySqlCommand command = start.CreateCommand();
command.CommandText = "SELECT id, muayine_adi, sabit_qiymet FROM tibbi_xidmetler WHERE id = '" + Id + "'";
start.Open();
MySqlDataAdapter oxu = new MySqlDataAdapter(command);
DataTable dt = new DataTable();
oxu.Fill(dt);
if (dt != null && dt.Rows.Count > 0)
{
int idx = dataGridView2.Rows.Count - 1;
dataGridView2.Rows.Add(dt.Rows.Count);
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
int rVal = (idx + i) + 1;
dataGridView2.Rows[rVal].Cells["id"].Value = dt.Rows[i]["id"].ToString();
dataGridView2.Rows[rVal].Cells["muayine_adi"].Value = dt.Rows[i]["muayine_adi"].ToString();
dataGridView2.Rows[rVal].Cells["sabit_qiymet"].Value = dt.Rows[i]["sabit_qiymet"].ToString();
}
}
start.Close();
}
}

How to populate a combo box from another combo box in the same form?

Two comboBox and a table called MAINCATE is created.
I have a code , but stuck to determine what SQLQuery should i use to get the second combo box filled , determined by the first combo box.
I just need a little help on how to fill in the second combobox based on mainCate picked by the first combobox..
i need to do something like.. if combobox 1 mainCate is "Food" , then combo box 2 should show "Raw , cooked , fruits and vegetables"
This is what is inside of the MAINCATE table -
(http://i.imgur.com/qR90Z2B.png)
And this is my code :-
DataSet ds1;
DataSet ds2;
public User()
{
InitializeComponent();
}
private void User_Load(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Data Source=PEWPEWDIEPIE\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True";
conn.Open();
SqlDataAdapter daMain = new SqlDataAdapter("SELECT * FROM MAINCATE", conn);
ds1 = new DataSet();
daMain.Fill(ds1, "Maincate");
mainCatU.DisplayMember = "mainCate";
mainCatU.ValueMember = "mainCate";
mainCatU.DataSource = ds1.Tables["MAINCATE"];
mainCatU.DropDownStyle = ComboBoxStyle.DropDownList;
mainCatU.Enabled = true;
SqlDataAdapter daSub = new SqlDataAdapter("SELECT >What should i do here?<", conn);
ds2 = new DataSet();
daSub.Fill(ds2, "Subcate");
subCatU.DisplayMember = "Subcat1";
subCatU.ValueMember = "Subcat";
subCatU.DataSource = ds2.Tables["MAINCATE"];
subCatU.DropDownStyle = ComboBoxStyle.DropDownList;
subCatU.Enabled = true;
conn.Close();
}
private void mainCatU_SelectionChangeCommitted(object sender, EventArgs e)
{
//have no idea if a code should be here..
}
or should i do something like this?
SqlCommand cmd = new SqlCommand("select Subcat1,Subcat2,Subcat3,Subcat4 from MAINCATE where mainCate=#mainCate;", con);
=========================================
#philip -
putting this on page load repalcing my code above - it didnt work..
string result = mainCatU.SelectedItem.ToString();
SqlDataAdapter daSub = new SqlDataAdapter("SELECT * FROM MAINCATE where mainCate = " + result , conn);
ds2 = new DataSet();
daSub.Fill(ds2, "Subcate");
subCatU.DisplayMember = "Subcat1";
subCatU.ValueMember = "Subcat1";
subCatU.DataSource = ds1.Tables["MAINCATE"];
subCatU.DropDownStyle = ComboBoxStyle.DropDownList;
subCatU.Enabled = true;
even tried
SqlDataAdapter daSub = new SqlDataAdapter("SELECT * FROM MAINCATE where mainCate=#result", conn);
Actually, you don't need another sql query,because you already get all maincate records from database.You can simply use dictionary to store this records.
First define a Dictionary<string,List<string>>
Define it here(!)
DataSet ds1;
DataSet ds2;
Dictionary<string,List<string>> allRecords = new Dictionary<string,List<string>>();
Then: (i edit your code)
SqlDataAdapter daMain = new SqlDataAdapter("SELECT * FROM MAINCATE", conn);
ds1 = new DataSet();
daMain.Fill(ds1, "Maincate");
DataTable dt = ds1.Tables["MAINCATE"];
foreach (DataRow dr in dt.Rows)
{
List<string> SubCats = new List<string> {
dr["Subcat1"].ToString(),
dr["Subcat2"].ToString(),
dr["Subcat3"].ToString(),
dr["Subcat4"].ToString()
};
allRecords.Add(dr["mainCate"].ToString(),SubCats);
mainCatU.Items.Add(dr["mainCate"].ToString());
}
mainCatU.DropDownStyle = ComboBoxStyle.DropDownList;
mainCatU.Enabled = true;
Then you need to handle mainCatU selectionchanged like this:
if(allRecords.ContainsKey(mainCatU.SelectedItem.ToString())) {
subCatU.DataSource = allRecords[mainCatU.SelectedItem.ToString()];
}
I think this is what your looking for:
Fill the first combo box with your current code.
Then to fill the second combo box you need to hook up the first combo box selectionchangecommitted. However why not just use the standard event?
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//Here use if statements to capture what value is set
if (comboBox1.SelectedIndex = 1)
//If selected value is Vehicles
{
//Then SELECT * FROM MainCate WHERE MainCate = 'Vehicles'
//This is possibly incorrect as I don't know how your DBTable is structured
//Same code as before
//Set this data to the second combobox
}
}
OK? So look into implementing this, if you want to refactor this you could, rather than using IF statements you could parametrise -
string result = comboBox1.SelectedItem.ToString();
SELECT * FROM MainCate WHERE MainCate = result
Obviously this won't compile so don't copy then paste it, then come back saying it doesn't work. It needs to be implemented like you did before, but rather than hardcode the result each time, use the parameter.
Personally I wouldn't have this all in one class, however you may prefer this way.
ComboBox1, ComboBox2 -- you just want to populate ComboBox2 using ComboBox1 Select change. So, At first bind your ComboBox1. Then cretae an event for ComboBox1:
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string value1 = ComboBox1 .SelectedValue.ToString();
LoadComboBox2 ();
}
And Get your ComboBox1 selected value and use it to populate ComboBox2 .
private void LoadComboBox2 ()
{
DataRow dr;
SqlConnection con = new SqlConnection(#"Data Source=name;Initial Catalog=dbName;User ID=sa;Password=sa123");
con.Open();
SqlCommand cmd = new SqlCommand("select id,name from table where id=#ID", con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
dr = dt.NewRow();
dr.ItemArray = new object[] { 0, "--Select--" };
dt.Rows.InsertAt(dr, 0);
ComboBox2 .ValueMember = "ID";
ComboBox2 .DisplayMember = "Name";
ComboBox2 .DataSource = dt;
con.Close();
}

Categories

Resources