Hello,
I am experiencing a 'strange behavior' using DataBinding to a database table and Windows Forms controls.
I have a very normal table in SQL Server Express.
I have a form with a DataGridView and a TextBox. Both of them are data bounded to the SQL server table using a BindingSource.
The BindingSource has a DataTable filled by a suitable adapter as DataSource (bindingSource.DataSource = dataTable).
The binding must be bidirectional (i.e. SQL Server table must be updated through the form).
After loading data TextBox and DataGridView are correctly showing related data (TextBox shows the value in one of the columns of the DataGridView).
If I edit the value in the TextBox I can get it updated also in the DataGridView (sometimes I need to force change of cell or row in the DataGridView, sometimes the TextBox validation is enough: at the end I get the new value displayed in both the TextBox and the DataGridView cell).
If I try to update the database (dataAdapter.Update((DataTable)bindingSource.DataSource) the new value is not updated in the SQL Server table.
The only way to have the new value updated is to modify also another cell in the DataGridView.
In my mind using the same BindingSource should keep synchronized all bounded controls. In fact the UI is synchronized.
But it seems that the update of the TextBox is not enough to force values update to the SQL Server table.
I made a lot of attempts by forcing row states and changing other things, but I couldn't be able to get a 'correct' behavior: maybe I am missing something in the base concepts.
Code is:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Test_DataGridView
{
public partial class Form1 : Form
{
SqlConnection cn;
SqlDataAdapter da;
SqlCommandBuilder cb;
private BindingSource bs;
public Form1()
{
InitializeComponent();
LoadData();
}
private void LoadData()
{
// SQLConnection
string connectionString = @"Data Source=(local)\SQLExpress; Initial Catalog=BKSProductRepository; Integrated Security=True;";
cn = new SqlConnection(connectionString);
cn.Open();
// SQLDataAdapter
da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand("SELECT * FROM ProductRepository WHERE Product_Id = 22", cn);
// SqlCommandBuilder
cb = new SqlCommandBuilder(da);
// DataTable
DataTable dt = new DataTable();
da.Fill(dt);
// BindingSource
bs = new BindingSource();
bs.DataSource = dt;
// Bind DataGridView to BindingSource
dgvGrid.DataSource = bs;
// Bind TextBox to BindingSource
Binding binding = new Binding("Text", bs, "Product_SetUpId", true, DataSourceUpdateMode.OnPropertyChanged);
txtProductSetUpID.DataBindings.Add(binding);
}
private void Save()
{
// Update database through DataAdapter
int result = da.Update((DataTable)bs.DataSource);
Debug.WriteLine("Affected rows: " + result);
}
private void btnSave_Click(object sender, EventArgs e)
{
Save();
}
}
}
Any help and suggestion will be appreciated.
Best regards
Alberto Utili