2016-07-27 29 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インデックス) で値を持っていません

未処理の例外は、このアプリケーションで発生した..::オブジェクトのインスタンスに設定されていない オブジェクト参照

は、このエラーの後、私はこのエラーを取得します。

1)保存ボタン::)

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読み込みボタン:それはDataGridViewの変更や更新のデータベースから変更を取得クリックで

だから、私は2つのボタンを持っていることは、すべての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(); 
     } 
012:データベースから

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

スレッドの問題です。データソースがワーカースレッドから変更され、データソースがdgvにバインドされ、dgvが同期外れ(多かれ少なかれ)している場合、UIスレッドで更新しようとします...ブームで例外が発生します – ASh

+0

MySQLレコードBackgroundWorkerなしで約7000)?アプリケーションはBackgroundWorkerなしで遅れていないようです。 – Mantoshelis

答えて

0

私はあなたのコードで簡単に見てきましたし、私の目は、この部分で停止:あなたが持っている場合ことを意味している行と列は、同じ長さであるかのようにこのコードは、データテーブルを処理

int i = 0; 

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

列よりも列数が多い場合は、範囲外のアクセス権があります。これは、「時には動作する」問題を説明します。

私はそれが助けてくれることを願っています:)

+0

いいえ、行と列の数値が常に等しいため、この部分はエラーをスローできません。 – Mantoshelis

関連する問題