2010-02-15 87 views
7

所以我有這個datagridview鏈接到綁定到綁定到基礎數據表的綁定源。問題是我需要手動將行添加到datagridview。DataBinding困境

這在綁定時無法完成,所以我必須使用數據綁定。

如果我將行添加到底層數據表中,當保存數據表時,行被複制,可能是因爲綁定源以某種方式獲得了副本的保留並將其也插入。

將它添加到綁定源是我一直在嘗試做的,但它不是很工作。

讓我解釋一下我的設置是什麼:

我有兩個表的數據庫: CashReceiptTable和CashReceiptItemsTable

CashReceiptItemsTable包含FK到CashReceiptTable。

該表格允許用戶添加和修改兩個表格。

當用戶輸入新的cashreceipt時,現金收據的ID爲-1,cashReceiptitemstable中的FK爲-1。保存數據庫時,cashReceipt的ID會更新,我必須手動更新cashreceiptitem的FK。

這裏有問題:

當我嘗試更新多行的CashReceiptID(在FK)在cashreceiteitems綁定源,第一行被更新,並消失(因爲它的過濾),以及其他行將被刪除,並且我無法再訪問它們。

我不知道爲什麼這是,我還沒有更新過濾器,所以他們仍然應該在那裏,但試圖訪問它們拋出RowNotInTableException。

我已經管理了一個工作,將綁定源中的行復制到內存數組中,刪除綁定源中的第一行(所有其他行都消失),更新行的FK並重新插入它們進入綁定源並保存表格。

這工作正常,但爲什麼行消失?

我還有一個小問題。當CashReceiptsTable爲空時,我正在向它添加一個新行,如果向CashReceiptsItemTable添加多行,它會導致問題。當手動將項目添加到綁定源時,添加一個新行將彈出到上一行關閉並將其推送到數據表。這隱藏它從我的FK更新例程中,它會丟失,它也將其從DataGridView中刪除。

只有這樣做,當我將第一行添加到CashReceiptsTable。爲什麼要這樣做,我該如何解決?

我張貼我的代碼,這裏會自動填入它:

 private void autopopulate(decimal totalPayment) { 
      //remove old rows 
      for (int i = 0; i < tblCashReceiptsApplyToBindingSource.List.Count; i++) { 
       DataRowView viewRow = tblCashReceiptsApplyToBindingSource.List[i] as DataRowView; 
       RentalEaseDataSet.tblCashReceiptsApplyToRow row = viewRow.Row as RentalEaseDataSet.tblCashReceiptsApplyToRow; 

       if (row.CashReceiptsID == this.ReceiptID) { 
        tblCashReceiptsApplyToBindingSource.List.Remove(viewRow); 
        i--; 
       } 
      } 

      decimal payment = totalPayment; 

      //look for an exact amount 
      foreach (DataGridViewRow dueRow in dataViewDueRO.Rows) { 
       decimal due = -1 * (Decimal)dueRow.Cells[Due.Index].Value; 
       if (due == payment) { 
        String charge = (String)dueRow.Cells[Description.Index].Value; 
        int chargeID = ManageCheckbooks.findTransactionID(charge); 

        tblCashReceiptsApplyToBindingSource.AddNew(); 

        RentalEaseDataSet.tblCashReceiptsApplyToRow row = ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row as RentalEaseDataSet.tblCashReceiptsApplyToRow; 
        row.CashReceiptsID = this.ReceiptID; 
        row.ApplyTo = chargeID; 

        row.Paid = payment; //convert to positive 

        payment = 0; 
        break; 
       } 
      } 

      //if the exact amount was found, payment will = 0, and this will do nothing, otherwise, 
      //divy out everything left over (which will be everything) 
      foreach (DataGridViewRow dueRow in dataViewDueRO.Rows) { 
       String charge = (String)dueRow.Cells[Description.Index].Value; 
       decimal due = (Decimal)dueRow.Cells[Due.Index].Value; 

       if (due > 0 || payment <= 0) { 
        continue; 
       } 

       int chargeID = ManageCheckbooks.findTransactionID(charge); 

       payment += due; //due is negative, so this will subtract how much the user owes 

       tblCashReceiptsApplyToBindingSource.AddNew(); 

       RentalEaseDataSet.tblCashReceiptsApplyToRow row = ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row as RentalEaseDataSet.tblCashReceiptsApplyToRow; 
       row.CashReceiptsID = this.ReceiptID; 
       row.ApplyTo = chargeID; 

       if (payment >= 0) { 
        //payment is enough to cover this 
        row.Paid = due * -1; //convert to positive 
       } else { 
        //doesn't have enough money to conver this, can only cover partial, or none 
        row.Paid = (due - payment) * -1; //math: 
        //money remaining $50, current charge = $60 
        //payment = 50 + -60 = -10 
        //row["Paid"] = (-60 - -10) * -1 
        //row["Paid"] = (-60 + 10) * -1 
        //row["Paid"] = -50 * -1 
        //row["Paid"] = 50 
       } 

       if (payment <= 0) { 
        break; //don't conintue, no more money to distribute 
       } 
      } 

      isVirginRow = true; 
     } 

這是它保存到數據庫中的函數:

protected override void saveToDatabase() { 
     tblCashReceiptsBindingSource.EndEdit(); 
     isVirginRow = false; 

     RentalEaseDataSet.tblCashReceiptsRow[] rows = rentalEaseDataSet.tblCashReceipts.Select("ID < 0") as RentalEaseDataSet.tblCashReceiptsRow[]; 
     int newID = -1; 
     if (rows.Count() > 0) { 
      tblCashReceiptsTableAdapter.Update(rows[0]); 
      newID = rows[0].ID; 
     } 

     tblCashReceiptsTableAdapter.Update(rentalEaseDataSet.tblCashReceipts); 


     //update table 
     /*foreach (RentalEaseDataSet.tblCashReceiptsApplyToRow row in rentalEaseDataSet.tblCashReceiptsApplyTo.Select("CashReceiptsID = -1")) { 
      row.CashReceiptsID = newID; 
     }*/ 

     //update binding source 
     DataRowView[] applicationsOld = new DataRowView[tblCashReceiptsApplyToBindingSource.List.Count]; 
     RentalEaseDataSet.tblCashReceiptsApplyToRow[] applicationsNew = new RentalEaseDataSet.tblCashReceiptsApplyToRow[tblCashReceiptsApplyToBindingSource.List.Count]; 
     tblCashReceiptsApplyToBindingSource.List.CopyTo(applicationsOld, 0); 
     for (int i = 0; i < applicationsOld.Count(); i++) { 
      RentalEaseDataSet.tblCashReceiptsApplyToRow row = applicationsOld[i].Row as RentalEaseDataSet.tblCashReceiptsApplyToRow; 

      if (row.CashReceiptsID < 0) { 
       applicationsNew[i] = rentalEaseDataSet.tblCashReceiptsApplyTo.NewRow() as RentalEaseDataSet.tblCashReceiptsApplyToRow; 
       applicationsNew[i]["ID"] = row.ID; 
       applicationsNew[i]["CashReceiptsID"] = this.ReceiptID; 
       applicationsNew[i][2] = row[2]; 
       applicationsNew[i][3] = row[3]; 
       applicationsNew[i][4] = row[4]; 
       //row.Delete(); 
      } 
     } 
     for (int i = 0; i < applicationsOld.Count(); i++) { 
      try { 
       if ((int)applicationsOld[i].Row["ID"] < 0) { 
        applicationsOld[i].Row.Delete(); 
       } 
      } catch (RowNotInTableException) { 
       break; 
      } 
     } 
     this.tblCashReceiptsApplyToBindingSource.Filter = "CashReceiptsID = " + this.ReceiptID; 

     foreach (DataRow newRow in applicationsNew) { 
      if (newRow == null) { 
       break; 
      } 
      tblCashReceiptsApplyToBindingSource.AddNew(); 
      ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[0] = newRow[0]; 
      ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[1] = newRow[1]; 
      ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[2] = newRow[2]; 
      ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[3] = newRow[3]; 
      ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[4] = newRow[4]; 
     } 

     tblCashReceiptsApplyToBindingSource.EndEdit(); 

     checkForBadRows(); 

     tblCashReceiptsApplyToTableAdapter.Update(rentalEaseDataSet.tblCashReceiptsApplyTo); 
     tblCashReceiptsApplyToTableAdapter.Fill(rentalEaseDataSet.tblCashReceiptsApplyTo); 
    } 
+0

我有一個問題,我認爲是基本相同的。我認爲整體的問題是:如何更改一個DataTable,不搞亂是在UI綁定的數據視圖? –

+0

你有沒有得到這方面的決議? –

回答

1

你可能想嘗試添加行到DataGridView的。由於你綁定了它,DataGridView成爲你的'接入點'。

我有一個綁定的DataGridView和大多數情況下,當我添加行我通過在DataGridView這樣做的幾個應用程序。它已經具有可以相對容易地添加的屬性/方法/事件。

如果您需要更多信息,我可以更新。

+0

我在這個問題中聲明,如果我將行添加到DataGridView中,它將在數據庫中複製它們。我在發佈後的第二天就解決了這個問題,但我不記得該修復程序是什麼。 – Malfist

+0

我看到的全部是「我將這些行添加到基礎數據表中,當數據表被保存時,這些行被複制,」。我沒有看到任何談論的DataGridView和複製,但我可能是失蹤了。 –

+0

我一定是在想我遇到的另一個問題。對不起,通過我的代碼去,我發現,我已經從添加一行到數據集添加行到DataGridView改變了它,所以我必須採取你的建議。 'viewApplications.Rows.Add(新的對象[] { -1, this.ReceiptID, chargeID, 的String.Format( 「$ {0:N}」,paidThisTime) 「」 });' – Malfist