2016-07-27 156 views
0

我在使用DataGridView時遇到了問題。我有一個包含5個表的數據集,這些表是從MySQL數據庫填充的。我有一個5個節點的TreeView。在每個TreeNode上,我將每個表綁定到DataGridView以更改產品列表。無法擺脫.NET DataGridView錯誤 - 索引沒有值

所以,如果我刪除或更新現有的DataGridView行並保存它有時我在下面得到錯誤,但有時它像一個魅力。我勒個去?

System.IndexOutOfRangeException:索引的 'x' 不爲 System.Windows.Forms.DataGridViewViewDataConnection.GetError(的Int32 rowIndex位置)具有在System.Windows.Forms.CurrencyManager.get_Item(的Int32索引) 值

這個錯誤後,我得到這個錯誤:

未處理的異常在此應用程序發生..:不設置到對象的實例 對象引用。

所以,我有2個按鈕:

1)保存按鈕:點擊它獲得從DataGridView的變化而變化,並更新數據庫:

try 
      { 
       /// Prisijungimas prie MySQL duombazes 
       var dbConnection = DBConnection.Instance(); 
       dbConnection.DatabaseName = "amber"; 

       /// Tikrinama, ar prisijungta 
       if (dbConnection.IsConnect()) 
       { 
        /// Gaunami pakeitimai iš DataGridView 
        DataTable changes = ((DataTable)itemsDataGridView.DataSource).GetChanges(); 

        if (changes != null) 
        { 
         DataTable columnsSchema = GetColumnNamesByTable(menuTreeView.SelectedNode.Tag.ToString()); 

         /// Surašomi originalūs stulpelių pavadinimai 
         /// iš MySQL duombazės lentelės 
         int i = 0; 

         foreach (DataRow row in columnsSchema.Rows) 
          changes.Columns[i++].ColumnName = row.Field<String>("ColumnName"); 

         /// Atliekami paketiimai MySQL duombazėje 
         if (itemsDataGridView.RowCount > 0 && CheckIfAllRowValuesExist(changes)) 
         { 
          using (MySqlDataAdapter mySqlDataAdapter = new MySqlDataAdapter("SELECT * FROM " + menuTreeView.SelectedNode.Tag.ToString(), dbConnection.Connection)) 
          { 
           MySqlCommandBuilder mcb = new MySqlCommandBuilder(mySqlDataAdapter); 
           mySqlDataAdapter.UpdateCommand = mcb.GetUpdateCommand(); 
           int affectedRows = mySqlDataAdapter.Update(changes); 
           ((DataTable)itemsDataGridView.DataSource).AcceptChanges(); 

           /// Jei yra paveiktų eilučių, tai sėkmingai atnaujinta 
           if (affectedRows > 0) 
           { 
            MessageBox.Show("Sėkmingai atnaujinta", "Pranešimas", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Information); 
           } 
          } 
         } 
         else 
         { 
          MessageBox.Show("Prašome užpildyti visus laukus"); 
         } 
        } 
        else 
         MessageBox.Show("Nebuvo ką atnaujinti", "Pranešimas", 
             MessageBoxButtons.OK, 
             MessageBoxIcon.Information); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.ToString()); 
      } 

      finally 
      { 
       loadButton.PerformClick(); 
      } 

2)Load按鈕:它得到所有5個表從數據庫:

loadButton.Enabled = false; 
      /// Jei BackGroundWorker neužsiėmės pradedame darbą 
      if (getItemsBackgroundWorker.IsBusy == false) 
       getItemsBackgroundWorker.RunWorkerAsync(); 

      /// Keičiame statusą 
      statusLabel.Text = "Gaunama"; 

3)

private void getItemsBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      GetKidsOrAdultsOrPetsAllRecords(); 
     } 

4)

public void GetKidsOrAdultsOrPetsAllRecords() 
     { 
      /// Jungiames prie MySQL duombazės 
      var dbConnection = DBConnection.Instance(); 
      dbConnection.DatabaseName = "amber"; 
      try 
      { 
       if (dbConnection.IsConnect()) 
       { 
        string query = null; 
        query = "SELECT code as 'Kodas', quantity as 'Kiekis', color as 'Spalva', length as 'Ilgis', clasp as 'Užsegimas', thread as 'Siūlas', description as 'Aprašymas' FROM kids;" + 
          "SELECT code as 'Kodas', quantity as 'Kiekis', color as 'Spalva', length as 'Ilgis', clasp as 'Užsegimas', thread as 'Siūlas', description as 'Aprašymas' FROM adults;" + 
          "SELECT code as 'Kodas', quantity as 'Kiekis', color as 'Spalva', length as 'Ilgis', clasp as 'Užsegimas' FROM pets;" + 
          "SELECT code as 'Kodas', quantity as 'Kiekis', color as 'Spalva', image as 'Nuotrauka' FROM jewelry;" + 
          "SELECT code as 'Kodas', title as 'Pavadinimas', size as 'Dydis', weight as 'Svoris' FROM spareParts"; 

        using (MySqlDataAdapter adapter = new MySqlDataAdapter(query, dbConnection.Connection)) 
        { 
         dataSet.Clear(); 
         adapter.Fill(dataSet); 
         if (dataSet.Tables.Count > 0) 
         { 
          /// Keičiame apatinį statusą 
          statusLabel.Text = "Visi įrašai gauti"; 
         } 
        } 

        BeginInvoke((MethodInvoker)delegate 
        { 
         menuTreeView.Enabled = true; 
        }); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.ToString()); 
       statusLabel.Text = "Nepavyko gauti įrašų iš MySQL bazės"; 
      } 

      finally 
      { 
       dbConnection.Close(); 
      } 

5)這就是我如何綁定物品的DataGridView:

private void menuTreeView_AfterSelect(object sender, TreeViewEventArgs e) 
     { 
      /// Tikriname, iš kurios MySQL lentelės imti duomenis 
      /// pagal TreeNode tag'ą 
      if (e.Node.Parent != null && (e.Node.Parent.Name == "wareHouseRoot")) 
      { 
       saveButton.Visible = true; 
       deleteButton.Visible = true; 
       addButton.Visible = true; 
       table = e.Node.Tag.ToString(); 
      } 
      else 
      { 
       saveButton.Visible = false; 
       deleteButton.Visible = false; 
       addButton.Visible = false; 
      } 

      /// Padarome rezultatų GroupBox'ą nematomu 
      foreach (Control control in Controls) 
      { 
       if (control is GroupBox && (control.Name.ToString() != "searchGroupBox")) 
        control.Visible = false; 
      } 

      itemsDataGridView.DataSource = null; 

       /// Tikriname TreeNode pavadinimus ir 
       /// nustatome GroupBox'ams pavadinimus, matomumą 
       /// ir siunčiame užklausą gauti įrašams 
       switch (e.Node.Name) 
       { 
        case ("kidsNode"): 
         this.recordsGroupBox.Text = "Vaikų prekės"; 
         this.recordsGroupBox.Visible = true; 
         itemsDataGridView.DataSource = dataSet.Tables[0]; 
         break; 
        case ("adultsNode"): 
         this.recordsGroupBox.Text = "Suaugusiųjų prekės"; 
         this.recordsGroupBox.Visible = true; 
         itemsDataGridView.DataSource = dataSet.Tables[1]; 
         break; 
        case ("petsNode"): 
         this.recordsGroupBox.Text = "Gyvūnų prekės"; 
         this.recordsGroupBox.Visible = true; 
         itemsDataGridView.DataSource = dataSet.Tables[2]; 
         break; 
        case ("jewelryNode"): 
         this.recordsGroupBox.Text = "Juvelyrika"; 
         this.recordsGroupBox.Visible = true; 
         itemsDataGridView.DataSource = dataSet.Tables[3]; 
         itemsDataGridView.Columns[3].Visible = false; 
         jewelryGroupBox.Visible = true; 
         break; 
        case ("sparePartsNode"): 
         this.recordsGroupBox.Text = "Detalės"; 
         this.recordsGroupBox.Visible = true; 
         this.itemsDataGridView.DataSource = dataSet.Tables[4]; 
         break; 
        case ("amberRoot"): 
         this.controlPanelGroupBox.Visible = true; 
         break; 
       } 
     } 

我卡在此問題,並不能找到解決辦法。我嘗試了在Google,Stackoverflow和其他論壇中找到的所有解決方案,但仍然無法擺脫它。

+0

是線程問題,我猜。 datasource從工作線程修改,datasource綁定到dgv,dgv嘗試在UI線程中更新,如果它們不同步(這是隨機的或多或少)...繁榮,發生異常 – ASh

+0

我可以填充MySQL記錄(約7000)沒有BackgroundWorker?如果沒有BackgroundWorker,應用程序似乎不會運行。 – Mantoshelis

回答

0

我簡要地看着你的代碼和我的眼睛在這部分停:

int i = 0; 

foreach (DataRow row in columnsSchema.Rows) 
    changes.Columns[i++].ColumnName = row.Field<String>("ColumnName"); 

此代碼處理你的數據表猶如行和列在相同的長度,這意味着,如果你有比列更多的行,你有一個超出範圍訪問 - 這將解釋你的'有時候工作'的問題。

我希望它有助於:)

+0

不,這部分不能拋出錯誤,因爲行號和列號始終相等。 – Mantoshelis