2010-02-15 6 views
7

그래서 기본 데이터 테이블에 바인딩하는 바인딩 소스에 연결된이 datagridview가 있습니다. 문제는 내가 수동으로 datagridview에 행을 추가해야합니다.DataBinding 번거 로움

바인딩되는 동안이 작업을 수행 할 수 없으므로 데이터 바인딩 작업을해야합니다.

데이터 테이블을 저장할 때 행을 기본 데이터 테이블에 추가하면 행이 복제됩니다. 아마도 바인딩 소스가 복사본을 보유하고이를 삽입했기 때문일 수 있습니다.

바인딩 소스에 추가하는 것은 내가 해왔지만 아직 제대로 작동하지 않습니다.

내 설정이 정확히 무엇인지 설명하자 CashReceiptTable 및 CashReceiptItemsTable

CashReceiptItemsTable가 CashReceiptTable에 FK를 포함

나는 두 개의 테이블이있는 데이터베이스가 있습니다.

이 양식을 사용하면 사용자가 두 테이블을 추가하고 수정할 수 있습니다.

사용자가 새 cashreceipt를 입력하면 현금 영수증의 ID는 -1이고 cashReceiptitemstable의 FK는 -1입니다. 데이터베이스가 저장되면 cashReceipt의 ID가 업데이트되고 cashreceiptitem의 FK를 수동으로 업데이트해야합니다. (이 필터링 있기 때문에)

나는 소스를 바인딩 cashreceiteitems에 둘 이상의 행에서 CashReceiptID합니다 (FK)를 업데이트하려고

는, 첫 번째 행이 업데이트되고 사라지고 : 여기

는 문제가 있습니다 다른 행이 제거되고 더 이상 액세스 할 수 없습니다.

이유가 무엇인지 모르겠지만 아직 필터를 업데이트하지 않았으므로 필터가 여전히 있어야하지만 RowNotInTableException을 throw하려고합니다.

바인딩 소스의 행을 메모리 배열로 복사하고 바인딩 소스의 첫 번째 행을 삭제하며 (다른 모든 행은 사라짐) 행의 FK를 업데이트하고 다시 삽입합니다. 바인딩 소스에 저장하고 테이블을 저장하십시오.

이 작업은 정상적으로 수행되지만 행이 사라지는 이유는 무엇입니까?

나는 또한 하나의 약간의 문제가 있습니다. CashReceiptsTable이 비어 있고 새 행을 추가 할 때 CashReceiptsItemTable에 둘 이상의 행을 추가하면 문제가 발생합니다. 항목을 바인딩 소스에 수동으로 추가 할 때 새 행을 추가하면 이전 행이 꺼지고 데이터 테이블에 푸시됩니다. 이렇게하면 내 FK 업데이트 루틴에서 숨겨져 손실되고 DataGridView에서도 제거됩니다.

은 CashReceiptsTable에 첫 번째 행을 추가 할 때 수행합니다. 왜이 작업을 수행하고 어떻게 해결할 수 있습니까?

난 여기가 autopopulates 내 코드를 게시하도록하겠습니다 :

 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

나는 기본적으로 같다고 생각하는 문제가 있습니다. 전체적인 문제는 : UI에 바인딩 된 DataView를 엉망으로 만들지 않고 DataTable을 변경하는 방법입니다. –

+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