2017-04-11 46 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。我想問你一個問題的傢伙。雖然這個解決方案解決了錯誤,我的代碼無法顯示在組合列旁邊的文本框列中的值,但列仍然爲空。我該如何解決它? –