我正在尝试在datagridview中进行编程。我想要的结果是这样的:当我点击datagridview的第一列(这是组合框列)时,数据库中的值应显示在下一列(文本框列)中。
我得到了这个例外:
指数超出范围。必须是非负的
在这一行:
DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[0];
e.RowIndex显示-1值。
现在我感到被这个代码困住了。可能是什么问题呢。任何人都可以帮助我吗?
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
dataGridView1.CellValueChanged +=
new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
dataGridView1.CurrentCellDirtyStateChanged +=
new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);
}
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (this.dataGridView1.IsCurrentCellDirty)
{
// This fires the cell value changed handler below
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[0];
// ******** e.rowindex shows -1 value.
if (cb.Value != null)
{
con.Open();
SqlCommand cmd = new SqlCommand("select rate FROM Ratemaster where Packagetype = '" + comboBox1.Text +
"' AND Tickettype ='" + ComboboxColumn.Selected + "' ", con);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
dataGridView1.Rows[0].Cells[1].Value = dr[0].ToString();
//dataGridView1.Rows[e.RowIndex].Cells[1].Value = "hi";
}
else
{
//txtRate.Text = "0";
}
con.Close();
}
}
答案 0 :(得分:2)
我确实解决了这个问题,使用了一个捕获并忽略-1范围的包装器。
if(e.RowIndex >= 0)
foo();
else
bar();
和
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if(e.RowIndex >= 0)
{
DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[0];
// ******** e.rowindex shows -1 value.
if (cb.Value != null)
{
con.Open();
SqlCommand cmd = new SqlCommand("select rate FROM Ratemaster where Packagetype = '" + comboBox1.Text +
"' AND Tickettype ='" + ComboboxColumn.Selected + "' ", con);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
dataGridView1.Rows[0].Cells[1].Value = dr[0].ToString();
//dataGridView1.Rows[e.RowIndex].Cells[1].Value = "hi";
}
else
{
//txtRate.Text = "0";
}
con.Close();
}
}
答案 1 :(得分:2)
@kury的回答是正确的,但似乎忽略了这样一个事实,即当任何单元格值发生变化时会触发这一事实。为了使其正常工作...您还需要确保值实际上是组合框单元格。因此,需要进行另一项检查以确保COMBO BOX值已更改:
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (e.RowIndex >= 0) {
if (e.ColumnIndex == 0) {
DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[0];
//.....
//.....
}
}
}
答案 2 :(得分:0)
而不是分配' CellValueChanged' dataGridView1_EditingControlShowing()中的事件,尝试从设计视图中分配事件;使用属性窗口。
似乎每个EditingControlShowing()事件都是' CellValueChanged'事件正在堆叠并一次又一次地被调用,这意味着当EditingControlShowing()触发器第一次调用CellValueChanged时,下一次它将被调用两次并继续。