首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DataBinding困境

DataBinding困境
EN

Stack Overflow用户
提问于 2010-02-15 22:23:18
回答 1查看 882关注 0票数 7

因此,我有这个datagridview,它链接到绑定源,绑定到基础数据表。问题是,我需要手动将行添加到datagridview。

这是不能做到的,因为它是绑定的,所以我必须使用数据库。

如果我将行添加到基础datatable中,则在保存datatable时,行将被复制,这可能是因为绑定源以某种方式获得了一个副本并将其插入。

将其添加到绑定源是我一直在尝试的工作,但它并不完全有效。

让我详细解释一下我的设置是什么:

我有一个有两个表的数据库: CashReceiptTable和CashReceiptItemsTable

CashReceiptItemsTable包含一个FK到CashReceiptTable。

该表单允许用户添加和修改这两个表。

当用户输入新的现金收据时,现金收据的id是-1,而cashReceiptitemstable中的FK是-1。当数据库被保存时,现金收集器的id会被更新,我必须手动更新现金收集器的FK。

以下是问题所在:

当我试图在多行中更新CashReceiptID ( FK)时,第一行将被更新,并消失(因为它已被过滤),其他行被移除,并且我无法再访问它们。

我不知道为什么,我还没有更新过滤器,所以它们应该仍然存在,但是尝试访问它们会抛出RowNotInTableException。

我管理了一项工作,将绑定源中的行复制到内存数组中,删除绑定源中的第一行(所有其他行都消失了),更新该行的FK并将它们重新插入绑定源并保存表。

这很好,但是为什么行会消失呢?

我还有一个轻微的问题。当CashReceiptsTable为空并且向其添加一个新行时,如果我向CashReceiptsItemTable中添加了多个行,则会导致问题。当手动将项添加到绑定源时,添加一个新行将弹出到上一行,并将其推入datatable。这隐藏了它对我的FK更新例程,它是丢失的,它也从DataGridView中删除它。

只有当我将第一行添加到CashReceiptsTable时,它才会这样做。它为什么要这样做,我怎样才能解决它?

我在这里张贴我的自动脉冲代码:

代码语言:javascript
复制
        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;
        }

这是将它保存到数据库中的函数:

代码语言:javascript
复制
    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);
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-02-18 10:31:30

您可能需要尝试将行添加到DataGridView。由于您是绑定到它,DataGridView成为您的‘接入点’。

我有几个绑定到DataGridView的应用程序,在大多数情况下,当我添加一行时,我都是通过DataGridView来实现的。它已经有了允许您相对容易地添加的属性/方法/事件。

如果你需要更多的信息我可以更新。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2269353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档