Reputation: 402
I have a form with a combo box and a datagridview control. The combo box is populated by a database table, and stores a Transaction ID.
When the combo box is updated, the Datagridview is bound to a database table, and displays the records associated with the Transaction ID from the combo box.
cboTransaction_SelectionChangeCommitted(object sender, EventArgs e)
{
int id = Convert.ToInt32(cboTransaction.SelectedValue);
db.Items.Where(i => i.TransactionId == id).Load();
bs.DataSource = db.Items.Local.ToBindingList();
dgv.DataSource = bs;
}
For the first record, this works fine. A user can select a transaction ID and add/edit Item records in the DataGridView without issue.
However, when a user selects a different Transaction from the combo box, things get a bit messier. Using the code above, the DataGridView does not clear the rows with the old ID number, but shows the old records + any records for the newly selected Transaction. I assumed that the Where() clause would limit the DataGridView to those items where the Transaction ID matched.
If I add db.SaveChanges();
and dgv.Rows.Clear();
to the beginning of that block, the rows are cleared successfully, however changes are not saved to the database.
I have also tried
db.Items.Load();
bs.DataSource = db.Items.Local.ToBindingList().Where(i => i.TransactionId == id);
This binds the Datagridview to the correct Transaction, but does not allow the user to add any new records.
How can I ensure that the datagridview displays only the records related to the desired transaction, while still allowing the user to add/edit records?
EDIT
I created a test form with a textbox, button and datagridview for testing, and have the same results. The Datagridview has a Datasource of the database table being edited.
public partial class frmTest : Form
{
private BindingSource bs = new BindingSource();
private UniformDataContainer db = new UniformDataContainer();
public frmTest()
{
InitializeComponent();
dataGridView1.DataSource = bs;
}
private void button1_Click(object sender, EventArgs e)
{
int id = Convert.ToInt32(textBox1.Text.ToString());
db.Items.Where(i => i.TransactionId == id).Load();
bs.DataSource = db.Items.Local.ToBindingList();
bs.ResetBindings(false);
}
private void dataGridView1_RowValidated(object sender, DataGridViewCellEventArgs e)
{
db.SaveChanges();
}
}
While debugging the code, I found that db.Items.Local
still contained the old rows, and did not seem to clear.
Upvotes: 0
Views: 3707
Reputation: 402
I managed to fix it / hack around it by disposing of my Database Conext, and re-connecting:
db.Dispose();
db = new UniformDataContainer();
int id = Convert.ToInt32(textBox1.Text);
db.Items.Where(i => i.TransactionId == id).Load();
bs.DataSource = db.Items.Local.ToBindingList();
This saves the existing records for the previous transaction, and clears the data grid after selecting a new transaction.
Thanks to @gzaxx and @SerkanOzvatan for your responses!
Upvotes: 0
Reputation: 241
You must set grid's DataSource to null before setting it.Like this :
cboTransaction_SelectionChangeCommitted(object sender, EventArgs e)
{
int id = Convert.ToInt32(cboTransaction.SelectedValue);
db.Items.Where(i => i.TransactionId == id).Load();
bs.DataSource = db.Items.Local.ToBindingList();
dgv.DataSource = null;
dgv.DataSource = bs;
}
Upvotes: 0
Reputation: 17590
Instead of rebinding DataSource
to DataGridView
after change, call ResetBindings
method that should reset grid with new values.
cboTransaction_SelectionChangeCommitted(object sender, EventArgs e)
{
int id = Convert.ToInt32(cboTransaction.SelectedValue);
db.Items.Where(i => i.TransactionId == id).Load();
bs.DataSource = db.Items.Local.ToBindingList();
bs.ResetBindings(false);
}
try it and see if that fixed your problems, if not I have one more suggestion, but this should do the job :)
Edit
Okay after your edit I see problem. First you have to clear local cache of your DB
class or bind to your where clause:
cboTransaction_SelectionChangeCommitted(object sender, EventArgs e)
{
int id = Convert.ToInt32(cboTransaction.SelectedValue);
var bindinglist = new BindingList(db.Items.Where(i => i.TransactionId == id).ToList());
bs.DataSource = bindinglist;
bs.ResetBindings(false);
}
Upvotes: 1