2013-06-13 56 views
0

我有一个组合框和一个datagridview控件的窗体。组合框由数据库表填充,并存储交易ID。基于Combobox值更新DataGridView

更新组合框时,Datagridview绑定到数据库表,并显示与组合框中的事务ID关联的记录。

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; 
} 

对于第一个记录,这工作正常。用户可以选择一个事务ID并在DataGridView中添加/编辑项目记录而不会出现问题。

但是,当用户从组合框中选择不同的事务时,事情会变得有点混乱。使用上面的代码,DataGridView不会清除具有旧ID号的行,但会显示旧记录+新选定事务的任何记录。我假定Where()子句将DataGridView限制为事务ID匹配的那些项目。

如果我将db.SaveChanges();dgv.Rows.Clear();添加到该块的开头,则会成功清除行,但不会将更改保存到数据库。

我也曾尝试

db.Items.Load(); 
bs.DataSource = db.Items.Local.ToBindingList().Where(i => i.TransactionId == id); 

这结合在DataGridView到正确的交易,但不允许用户添加任何记录。

如何确保datagridview仅显示与所需事务相关的记录,同时仍允许用户添加/编辑记录?

EDIT

我创建一个文本框,按钮和用于的datagridview测试的测试形式,并具有相同的结果。 Datagridview具有正在编辑的数据库表的数据源。

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(); 
} 
} 

在调试代码,我发现db.Items.Local仍然包含旧行,似乎并不清楚。

回答

0

我设法解决它/我的数据库Conext处置周围破解,并重新连接:

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(); 

这节省了上一个事务的现有记录,并清除选择新交易后的数据网格。

感谢@gzaxx和@SerkanOzvatan的回应!

1

更改后不重新键入DataSourceDataGridView,请调用ResetBindings方法,该方法应该使用新值重置网格。

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); 
} 

尝试一下,看看有没有什么固定你的问题,如果不是我有一个建议,但是这应该做的工作:)

编辑

好你的编辑后,我见问题。首先,你要清楚你的DB类或绑定的本地缓存到您的where子句:

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); 
} 
+0

没有运气我很害怕。 我已经创建了一个单独的测试表单(请参阅上面编辑的问题),但datagridview仍然显示以前的记录。我也注意到db.Items.Local仍然保存着以前的数据库记录。 –

+0

看到我的编辑,希望对你有用:) – gzaxx

+0

你的编辑清除了datagridview,但是它不会向数据库添加新记录。我瞎了,并认为我通过使用'db.Items.Local.Clear()',但它只会保存最近添加的记录。 –

0

你必须设置网格的DataSource设置之前为null。就像这样:

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; 
} 
+0

当'id'发生变化时,这不会删除以前的记录。 –