2010-02-15 13 views
7

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); 
    } 
+0

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? –

+0

¿Alguna vez obtuvo una resolución al respecto? –

Respuesta

1

Es posible que desee probar a añadir filas a la DataGridView.Como lo vincula a él, DataGridView se convierte en su "punto de acceso".

Tengo varias aplicaciones que se unen a DataGridView y para la mayoría de las circunstancias cuando agrego una fila lo hago a través de DataGridView. Ya tiene propiedades/métodos/eventos que le permiten agregar con relativa facilidad.

Si necesita más información, puedo actualizarla.

+0

Indico en la pregunta que si agrego las filas a DataGridView, las duplica en la base de datos. Solucioné este problema el día después de publicarlo, pero no recuerdo cuál fue la solución. – Malfist

+0

Todo lo que veo es "Agrego las filas a la tabla de datos subyacente, cuando la tabla de datos se guarda, las filas están duplicadas". No vi nada hablando de la vista de la cuadrícula de datos y la duplicación, pero podría extrañarlo. –

+0

Debo haber estado pensando en otro problema que tenía. Lo siento, revisando mi código, descubrí que lo he cambiado de agregar una fila al conjunto de datos para agregar una fila a la vista de cuadrícula de datos, así que debo haber seguido su consejo. 'ViewApplications.Rows.Add (nuevo objeto [] { -1, this.ReceiptID, chargeID, String.Format ("$ {0: N}", paidThisTime), "" });' – Malfist