I'm using the table adapter in C# where I created a DataGridView. When I double click a row, I am displaying all the cells in the row in textboxes in a different Form. After I edit the textboxes and click my save button, I would like to take the values from the textboxes and replace them in the database. I can see the changes on the DataGrid, however I am not able to save them in the database.
private void InventoryData_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
//make new form and display them there
ViewInventoryItem ViewItem = new ViewInventoryItem();
ViewItem.textBox1.Text = this.InventoryData.CurrentRow.Cells[1].Value.ToString();
ViewItem.textBox2.Text = this.InventoryData.CurrentRow.Cells[2].Value.ToString();
ViewItem.textBox3.Text = this.InventoryData.CurrentRow.Cells[3].Value.ToString();
ViewItem.ShowDialog();
if (ViewItem.DialogResult == DialogResult.OK)
{
//save button was pressed
this.InventoryData.CurrentRow.Cells[0].Value = ViewItem.textBox1.Text;
this.InventoryData.CurrentRow.Cells[1].Value = ViewItem.textBox2.Text;
this.InventoryData.CurrentRow.Cells[2].Value = ViewItem.textBox3.Text;
this.Validate();
this.InventoryData.EndEdit();
this.booksTableAdapter.Update(this.InventoryDataSet.Books);
}
}
Found the problem. In the Dataset the Table had only Fill and Get Data. Even after selecting the Wizard to add the other statements it was failing. After adding the UpdateQuery manually, the code works without issues. Thank you Crowcoder for pointing me in the right direction.
Using C# and Winform.
I read a couple of similar questions but couldn't find any great answers that could interlock with my code. So, bear with me and thank you in advance for helping me.
I have a single form that contains multiple User Controls. Inside the first user control, you can insert, update and delete records from the database. In the second User Control, there is a datagridview that is populated with all records.
The problem I have is that whenever I insert, update or delete a record inside the first user control. It won't refresh inside the datagridview when I swap to the second user control.
Beneath is the second user control that populates the datagridview
private void populate()
{
database.OpenConnection();
string query = "SELECT id, name, qoute, time, date from maintable";
SQLiteDataAdapter sda = new SQLiteDataAdapter(query, database.connection);
SQLiteCommandBuilder builder = new SQLiteCommandBuilder(sda);
var ds = new DataSet();
sda.Fill(ds);
dtgNav.DataSource = ds.Tables[0];
databas.CloseConnection();
}
private void Navigation_Load(object sender, EventArgs e)
{
populate();
dtgNav.Columns[0].HeaderText = "ID";
}
public void Refresh()
{
this.Refresh();
}
Beneath is the code for adding a record to the datagridview in the first user control
private void btnAdd_Click(object sender, EventArgs e)
{
database.OpenConnection();
string query = "INSERT INTO maintable (`id`, `name`, `qoute`, `time`,`date`) VALUES (#Id, #Name, #Qoute, #Time, #Date)";
SQLiteCommand command = new SQLiteCommand(query, database.connection);
command.Parameters.AddWithValue("#Id", tbxID.Text);
command.Parameters.AddWithValue("#Name", tbxName.Text.Trim());
command.Parameters.AddWithValue("#Qoute", tbxQoute.Text.Trim());
command.Parameters.AddWithValue("#Time", tbxTime.Text.Trim());
command.Parameters.AddWithValue("#Date", dtpDate.Value.ToString("yyyy-MM-dd"));
command.ExecuteNonQuery();
MessageBox.Show("Added new event into the database.");
database.CloseConnection();
usercontrol2.Refresh();
}
I would appreciate it if we found a way to refresh the datagridview when the button is clicked without changing the original code all too much.
You have a public void Refresh method in the second usercontrol, try modifying this.Refresh();, to say populate();. this should call your private void populate method that you called when loading which should reload the grid. Let me know if this helps.
I've create a datagridview that show me my data. Then I should click on a row and I'd like to show a form where I can update my values.
Is it possible go to the previous/next element of the datagridview in another form? Because I'd like to create two buttons that allow me to scan the whole table and update each value.
Can you help me, please? I really don't know where to start
EDIT: This is the code to show my data
public static string StringaConnessione = "Data Source=localhost;Database=db;userid=root;password='';";
public static MySqlConnection Connessione = new MySqlConnection(StringaConnessione);
void MostraBtnClick(object sender, EventArgs e)
{
Connessione.Open();
MySqlDataAdapter SDA=new MySqlDataAdapter("SELECT * FROM Acquisti",Connessione);
DataTable DATA= new DataTable();
SDA.Fill(DATA);
dataGridView1.DataSource=DATA;
Connessione.Close();
I have added a record to the underlying db and after I add the record i do a
datagridview.Refresh(); and i dont see the newly added record.
If i stop and start the application its there. What am I doing or not
doing?
Notes : button1 and datagridview is in different Forms.I made datagridview's Modifiers public. This project is ado.net project
public class CustomerService
{
public List<Customers> ShowAll()
{
List<Customers> customers = new List<Customers>();
SqlConnection conn = new SqlConnection("data source=.; database=custer; user id=sa; password=*****");
SqlCommand cmd = new SqlCommand(" select * from Customers ", conn.Open());
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Customer customer = new Customer ()
{
CustomerID = dr.GetInt32(0),
CustomerName = dr.GetString(1),
CustomerSurname = dr.GetString(2),
};
customers.Add(customer);
}
conn.Close();
return customers;
}
}
private void button1_Click(object sender, EventArgs e)
{
CustomerService service = new CustomerService();
if (txtCustomerName.Text != "" || txtCustomerSurname.Text != "")
{
customerservice.customerAdd(txtCustomerName.Text, txtCustomerSurname.Text);//this rows is other method .I am using for adding new customer
MessageBox.Show("Customer Added");
Form1.dataGridView1.DataSource = service.ShowAll();
Form1.dataGridView1.Refresh();
}
else
{
//……………
}
}
After adding the data to the DB, your application knows nothing about the data added. You need to load those data to memory. Retrieve all the data you want to display from the database and bind it explicitly to UI after doing operations on database.
EDIT:
Can you check what ShowAll() returns while debugging? Does it return you the data you actually want?
If it is a WPF application take a look here. The issue here is to tell your UI component that underlying data source has been changed, so the UI component reflects the changes made to data.
Again if it is a WPF application, you can define your data as ObservableCollection and bind you UI to this collection. ObservableCollection automatically requests UI to refresh when data has changed.
Rica ederim .)
The usual way of doing this is to reset the DataSource of the DataGridView.
Try like this code (with correct code to provide the right datasource):
Form1.dataGridView1.DataSource = typeof(List);
Form1.dataGridView1.DataSource = service.ShowAll();
Calling .Refresh() doesn't work since it only forces a repaint, but the code that paints the grid doesn't know of the changes.
Ref this WPF link also, that may help you:
Why does the DataGrid not update when the ItemsSource is changed?
Try calling EndEdit on the datagridview:
this.dataGridView1.EndEdit();
Second, refresh the grid view:
this.dataGridView1.Refresh();
And if that still doesn't work, try calling Refresh on the containing control
ParentControl.Refresh()
This will end up calling a repaint that might be needed.
what is the content of customerservice.customerAdd ?
Maybe it doesnt close the connection properly/doesnt flush the data into the db,and it only happens when you close your app(all memory is disposed,and all connections are closed/flushed).
Also - I suggest using a BindingSource that the grid is bound to,and changing its data source - it has event to notify the grid automaticallly if its data source has changed and that will cause it to refresh.
As you said these are in different forms, I think the pointer to Form1 doesn't point to the form that you want. you should pass the pointer of that form with this to this form.
When you are creating form 2 define like this:
Form2 = new Form2();
Form2.form1 = this;
Then your code should work.
It appears you're using a List as the datasource. I've found using a generic list is ok for read only data but for doing any kind of updates you need something with more power. I don't know about WPF but in winForms I've had great success with the IBindingList interface and the BindingList generic collection. The BindingList generic collection implements the IBindingList interface for you. I would read the MSDN articles on both of them. I've pretty much stopped using the IBindingList interface but it's still perfectly fine to implement.
http://msdn.microsoft.com/en-us/library/system.componentmodel.ibindinglist.aspx
http://msdn.microsoft.com/en-us/library/ms132679.aspx
The answer is to have the gridview connected to the BindingList<Customers> rather than the List<Customers> . Hope this will solve your problem...
If you change the List to a BindingList you'll have success. I threw together a sample which just had a DataGridView and a couple of Buttons on a Form.
button1 generates some fake data and assigns the datasource.
button2 adds another Customer to the underlying list.
The DataGridView is updated when the underlying BindingList changes.
Code:
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string SurName { get; set; }
}
public partial class Form1 : Form
{
BindingList<Customer> customers = new BindingList<Customer>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; ++i)
{
customers.Add(new Customer
{
Id = i,
Name = "Name" + i,
SurName = "Surname" + i
});
}
dataGridView1.DataSource = customers;
}
private void button2_Click(object sender, EventArgs e)
{
customers.Add(new Customer
{
Id = 22,
Name = "Newname",
SurName = "Newsurname"
});
}
}
Now, the reason this works is that BindingList<T> implements IBindingList, among other things, and that interface has, among other things, an event called ListChanged which is raised when the list or something in the list changes.
If you are not bound to use customer list strictly as data-source for datagridview then
Here is much better solution using datatable. You will get updated customer list and datagridview after insert
public class CustomerService
{
public DataTable ShowCustomers()
{
string cns = "data source=.; database=custer; user id=sa; password=*****";
SqlConnection conn = new SqlConnection(cns);
SqlDataAdapter da = new SqDataAdapter("select * from Customers", conn);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
private void button1_Click(object sender, EventArgs e)
{
CustomerService service = new CustomerService();
if (txtCustomerName.Text != "" || txtCustomerSurname.Text != "")
{
customerservice.customerAdd(txtCustomerName.Text,txtCustomerSurname.Text);
MessageBox.Show("Customer Added");
DataTable dt = service.ShowCustomers();
Form1.dataGridView1.DataSource = dt;
//If you also need customer list. Provide the DataTable and get list
List<Customers> customers = new List<Customers>();
for (int i=0;i<dt.Rows.Count;i++)
{
Customer customer = new Customer();
customer.CustomerID = Convert.ToInt32(dt.Rows[i][0]);
customer.CustomerName = dt.Rows[i][1].ToString();
customer.CustomerSurname = dt.Rows[i][2].ToString();
customers.Add(customer);
}
}
}
You need to do data binding only once not on every new record. That's the whole point of binding data to a control that all changes will be auto reflected.
Make customers a data member of the CustomerService class and change your code appropriately:
class CustomerService {
List<Customers> customers;
...
}
Next the binding code should be done once, maybe when the first record is added to the List<Customers>.
BindingSource binding = new BindingSource();
binding.DataSource = customers;
dataGridView1.DataSource = binding;
If you have done this right, every time any record is deleted or added to the customers collection, it should be automatically be reflected in the DataGridView control.
I think you must have used update panel and might not refreshing that
I think this will solve your problem, Check this........
DataGrid.CommitEdit();
DataGrid.Items.Refresh();
NOTE
CommitEdit() method will fire the RowEditEnding event, it is a endless loop. WPF does not allow to refresh the view while it is editing, since it may occur the endless loop. However, you could refresh the view after editing. Try to remove the RowEditEnding event handler (If Initialzed) , and do refresh for the Items; Then add the event handler back:
Using: ASP.NET 4, SQL 2008, C#
I'm writing a web app for our projects team to keep track of special project users. One thing they have asked is to export quick lists of data that they use often. For instance, what I'm trying to do here is give the team a button which will populate a TextBox with all the various email addresses that are saved in our SQL DB.
What I've been trying to do is bind the TextBox to a specific column in the DB. I already have a connection to the DB, and I've built a DataSet that queries for that specific column, and it works normally.
My question is, how do I tell ASP.NET to use the data from the DataSet to populate the Textbox? Here is the code I'm working with so far:
protected void btnGetNPMEmailAddresses_Click(object sender, EventArgs e)
{
txbResults.Text = "";
txbResults.DataBind(ObjectDataSource_Designee_EmailAddresses) // ??? My DataSet
}
I'm definitely crawling my way up the C# learning curve. Any help would be greatly appreciated!
Thanks,
Paul D.
Try something like this:
protected void btnGetNPMEmailAddresses_Click(object sender, EventArgs e)
{
// TODO:: Populate ObjectDataSource_Designee
DataSet dataSet = GetDS(ObjectDataSource_Designee);
string emails = string.Empty;
for (int i = 0; i < dataSet.Tables[0].Rows.Count; i++)
{
emails = emails + dataSet.Tables[0].Rows[i]["EmailAddresses"].ToString() + Environment.NewLine;
}
txbResults.Text = emails;
}
private DataSet GetDS(ObjectDataSource ods)
{
var ds = new DataSet();
var dv = (DataView)ods.Select();
if (dv != null && dv.Count > 0)
{
var dt = dv.ToTable();
ds.Tables.Add(dt);
}
return ds;
}
You can't databind to a textbox in ASP.Net.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.textbox_properties
There is no DataSource property. You can manually go through and grab what's in the dataset and put it into the textbox, but not bind it. Do you mean textbox?
Assuming you are returning only one row and col from the database, you can do something like below:
txbResults.Text = dataSet.Tables[0].Rows[0].Cols[0].ToString();
My suggestion would be to use "ExecuteScalar()" method that returns only one value instead of using DataAdapter/Dataset.
Hope this Helps!!
I would say
foreach(DataRow dr in DataTable)
{
Textbox.Text = Textbox.Text + dr;
}
if for some reason you HAVE to use a text box