2017-04-11 126 views
2

我想在datagridview中编程。我想要的结果是这样的:当我点击datagridview(这是combobox列)的第一列时,数据库中的值应显示在下一列(textbox列)中。在formload上得到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(); 

     } 
    } 

回答

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

感谢您的建议朋友。但是我没有得到foo()和bar()的含义。由于我是编程新手,我完全不理解。你能详细说明你的答案吗? –

+3

嗨,富和酒吧,特别是连字foobar是任何代码的常见占位符,你可以想象。我想表达一下,你应该用你自己的代码对if子句作出反应,并忽略其他路径。所以你会这样做: – kurdy

+2

@ V.Vaibhav很多时候,程序员会用'foo'和'bar'或'foobar'来演示一个例子。上面基本上是说'if(e.RowIndex> = 0)'然后做一些事情 - 其中'foo();'是什么(不管你想要你的代码做什么,然后用它替换'foo()')。代码的else部分也是如此。 –

0

的而不是分配 'CellValueChanged' 在dataGridView1_EditingControlShowing(事件),尝试分配从设计视图中的事件;使用属性窗口。

似乎每EditingControlShowing()事件中的“CellValueChanged”事件被堆叠起来,被一次又一次地叫,EditingControlShowing时,这意味着()触发第一次CellValueChanged被调用一次,下一次将是两次,去。

+0

虽然此解决方案可用于解决错误,我的代码无法显示在组合框旁边的文本框列中的值,该列保留空白。我该如何解决它?你可以帮我吗 ? –

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]; 
     //..... 
     //..... 
    } 
    } 
} 
+1

的确如此。我想你甚至可以检查DataGridViewCellEventArgs e是否确实有变化。(至少在WPF中有效) – kurdy

+0

@kurdy事件名称给出了单元格值DID更改的事实。所以你只需要检查它是哪个单元。 – JohnG

+0

谢谢@JohnG。我想问你一个问题的家伙。虽然这个解决方案解决了错误,我的代码无法显示在组合列旁边的文本框列中的值,但列仍然为空。我该如何解决它? –