así que tengo este DataGridView que está vinculada a una fuente de encuadernación que sea vinculante a una tabla de datos subyacente. El problema es que necesito agregar filas manualmente a la vista de cuadrícula de datos.DataBinding Aflicciones
Esto no se puede hacer mientras está enlazado, así que tengo que trabajar con el enlace de datos.
Si agrego las filas a la tabla de datos subyacente, cuando la tabla de datos se guarda, las filas están duplicadas, probablemente porque la fuente de enlace de alguna manera retuvo una copia y la insertó también.
Agregarlo a la fuente de encuadernación es lo que he estado tratando de hacer, pero no está funcionando del todo.
Me explico exactamente lo que mi configuración es:
Tengo una base de datos con dos tablas: CashReceiptTable y CashReceiptItemsTable
CashReceiptItemsTable contiene una FK a CashReceiptTable.
El formulario permite a los usuarios agregar y modificar las dos tablas.
Cuando el usuario introduce un nuevo recibo de caja, el ID del recibo de caja es -1, y el FK en cashReceiptitemstable es -1. Cuando se guarda la base de datos, identificación de cashReceipt está actualizada, y tengo que actualizar manualmente FK de cashreceiptitem.
Éstos son los problemas:
Cuando intento actualizar el CashReceiptID (FK) en más de una fila en cashreceiteitems fuente de unión, la primera fila se actualiza y desaparece (porque se filtra), y el otras filas se eliminan y ya no puedo acceder a ellas.
No tengo idea de por qué ocurre esto, aún no actualicé el filtro, por lo que todavía deberían estar allí, pero al intentar acceder a ellos se lanza RowNotInTableException.
He logrado un trabajo que copia las filas en el origen de enlace a una matriz de memoria, elimina la primera fila en el origen de enlace (todas las otras filas simplemente desaparecen), actualiza la FK de la fila y las reinserta en la fuente de enlace y guarde la tabla.
Esto funciona bien, pero ¿por qué desaparecen las filas?
que también tienen una más leve problema. Cuando el CashReceiptsTable está vacío y añado una nueva fila a la misma, si añado más de una fila a la CashReceiptsItemTable que cause problemas. Al agregar manualmente los elementos de unión a la fuente, añadiendo una nueva fila a fila anterior hace estallar fuera y lo empuja a la tabla de datos. Esto lo oculta a mi rutina de actualización FK y se pierde, sino que también elimina de la DataGridView.
Es solo lo hace cuando estoy agregando la primera fila a CashReceiptsTable. ¿Por qué hace esto y cómo puedo solucionarlo?
Quiero poner mi código que autopopulates aquí:
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;
}
y esta es la función que guarda en la base de datos:
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);
}
Tengo un problema que creo que es básicamente el mismo. Creo que el problema general es: ¿cómo hacer cambios en una DataTable, sin estropear la DataView que está enlazada en la interfaz de usuario? –
¿Alguna vez obtuvo una resolución al respecto? –