그래서 기본 데이터 테이블에 바인딩하는 바인딩 소스에 연결된이 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);
}
나는 기본적으로 같다고 생각하는 문제가 있습니다. 전체적인 문제는 : UI에 바인딩 된 DataView를 엉망으로 만들지 않고 DataTable을 변경하는 방법입니다. –
이것에 대한 해결책을 얻었습니까? –