【问题标题】:Progress bar exceeding max value进度条超过最大值
【发布时间】:2018-09-10 04:52:20
【问题描述】:

使用 ++ 操作递增值时,进度条超出最大值。在下面的代码中,我有一个大小为 6004 的记录集,当它绕过循环时,它设法达到 6006,即使我已经放置了一个 if 语句来捕获它,当它达到 value++ 以将进度条重置为零时隐藏面板。

    invoiceRecord = (SageDataObject240.InvoiceRecord)_workSpace.CreateObject(Resources.InvoiceRecord);


    pnlProgress.Visible = true;
    progBarSelectInvoices.Value = 0;
    progBarSelectInvoices.Maximum = invoiceRecord.Count;

    List<EdiInvoice> selectedInvoices = new List<EdiInvoice>();
    EdiInvoice invoice;

    DateTime fromDate = chkEnableFromDatePicker.Checked ? dtpFrom.Value.Date : DateTime.MinValue;
    DateTime toDate = chkEnableToDatePicker.Checked ? dtpTo.Value.Date : DateTime.MaxValue;
    int invoiceCount = 0;
    int progressCount = 0;
  int progresbarValue = 0;          
    int maxCount = invoiceRecord.Count + 1;
    while (invoiceRecord.MoveLast())
    {
        progresbarValue = progBarSelectInvoices.Value++;
        bool isPosted = (SDOHelper.Read<sbyte>(invoiceRecord, Resources.POSTED_CODE) == 1);

        if (isPosted)
        {
            int invoiceNo = SDOHelper.Read<int>(invoiceRecord, Resources.INVOICE_NUMBER);
            string invoiceCustomerReference = SDOHelper.Read<string>(invoiceRecord, Resources.ACCOUNT_REF);
            bool isValidCustomerReference = (invoiceCustomerReference == _selectedCustomer.Reference || _selectedCustomer.IncludeBranchInvoices && _selectedCustomer.BranchCodes.ContainsKey(invoiceCustomerReference));

            sbyte invoiceTypeCode = SDOHelper.Read<sbyte>(invoiceRecord, Resources.INVOICE_TYPE_CODE);
            bool isValidType = invoiceTypeCode >= 0 && invoiceTypeCode <= 5;

            string notes1 = SDOHelper.Read<string>(invoiceRecord, "NOTES_1");
            bool isExported = notes1.Length > 2 && notes1.Substring(0, 3).Equals("EDI", StringComparison.CurrentCultureIgnoreCase);

            DateTime invoiceDate = SDOHelper.Read<DateTime>(invoiceRecord, "INVOICE_DATE");
            bool isInDateRange = invoiceDate >= fromDate && invoiceDate <= toDate;

            if (isValidCustomerReference && isValidType && (!isExported || chkIncludeAlreadyExportedInvoices.Checked) && isInDateRange)
            {
                invoice = new EdiInvoice();
                invoice.Customer = string.Format("({0}), {1}", invoiceCustomerReference, SDOHelper.Read<string>(invoiceRecord, Resources.NAME));
                invoice.InvoiceNumber = invoiceNo;
                invoice.Date = SDOHelper.Read<DateTime>(invoiceRecord, "INVOICE_DATE").ToString("dd/MM/yyyy");
                invoice.Type = GetInvoiceOrCredit(invoiceTypeCode);
                invoice.DeliveryAddress = SDOHelper.Read<string>(invoiceRecord, Resources.DEL_ADDRESS_1);
                invoice.Nett = SDOHelper.Read<double>(invoiceRecord, Resources.BASE_TOT_NET) + SDOHelper.Read<double>(invoiceRecord, Resources.BASE_CARR_NET);
                invoice.Vat = SDOHelper.Read<double>(invoiceRecord, Resources.BASE_TOT_TAX) + SDOHelper.Read<double>(invoiceRecord, Resources.BASE_CARR_TAX);

                selectedInvoices.Add(invoice);
            }
        }
           invoiceCount = invoiceRecord.Count;
           progressCount = progBarSelectInvoices.Value;
        if (progressCount++ == maxCount || progressCount==invoiceCount )
        {
            progBarSelectInvoices.Value = 0;
            progressCount = 0;
            pnlProgress.Visible = false;
            Application.DoEvents();
        }
        else

        {
            progBarSelectInvoices.Value++;
            progressCount= progBarSelectInvoices.Value++;
        }
        Application.DoEvents();

【问题讨论】:

  • 你已经问过这个问题here
  • @HandbagCrab - 我也看过那个,但它略有不同,不幸的建议是“添加Application.DoEvents”我同意他们非常密切相关并且可能解决这个问题解决另一个问题。

标签: c# winforms


【解决方案1】:

如果我们了解这里发生的事情,希望这能帮助您弄清楚这一点。让我们看看当您进入第 6003 个循环时会发生什么。 我会假设 progBarSelectInvoices.Value == 6002 在这一点上:

这条线有什么作用?

progresbarValue = progBarSelectInvoices.Value++;

最后。 progresbarValue == 6004progBarSelectInvoices == 6003

progresbarValue 再也不会被使用,所以它可能只是被转储,但不确定

然后我们跳过并做一些其他的事情,然后点击这条线:

progressCount = progBarSelectInvoices.Value;

这里progressCount == 6003 然后我们这样做:

if (progressCount++ == maxCount || progressCount==invoiceCount)

那么这里会发生什么,如果 maxCount == 6004 而不是这个 if 的第一部分是 false 但现在是 progessCount == 6004。我们知道如果maxCount 是6004,那么invoiceCount == 6003(来自maxCount = invoiceRecord.Count + 1; 这一行),但现在progressCount == 6004 所以这也是错误的。这意味着我们执行 else 部分。

progBarSelectInvoices.Value++;
progressCount= progBarSelectInvoices.Value++;

这是做什么的?嗯,在第一行我们增加progBarSelectInvoices.Value,所以现在是6004。然后我们移动到第二行,我们将progressCount设置为6004,但是我们再次增加进度条的值,所以现在是6005 . 然后我们回到循环的顶部,我们做的第一件事是再次增加进度条,这将我们带到 6006。

就我个人而言,我尽量避免在 if 语句中使用 pre 或 post 递增语句,因为这会使代码难以阅读。在这种情况下,我绝对会建议不要这样做。

如何解决
解决此问题的一种方法 - 如果您确定您只有 6004 条记录,因此您只会执行该 while 循环 6004 次,那么只需执行此操作(注意,我建议您将增量移动到 while 循环的末尾以便您在指示进度之前实际完成工作)

while (invoiceRecord.MoveLast())
{
    // All your other code here
    progBarSelectInvoices.Value++;

如果您想确保不超过最大值,您可以添加一个快速检查

while (invoiceRecord.MoveLast())
{
    // All your other code here
    if (progBarSelectInvoices.Value < progBarSelectInvoices.Maximum)
        progBarSelectInvoices.Value++;

然后,您可以在检查 maxCount 并重置进度条或递增它的循环结束时取消 if/else 业务。

旁注
Application.DoEvents() 行的存在以及在增加进度条值时您没有收到异常的事实,我偷偷怀疑您正在 UI 线程中执行此循环。每当您发现自己需要在事件处理程序代码中添加Application.DoEvents() 时,这是问自己“如何才能将这项工作移出 UI 线程?”的好时机。打电话给Application.DoEvents() 几乎从来都不是一个好主意。见herehere

您应该将该代码移到后台线程中。唯一要记住的是,您需要使用调用调用来更新进度条值。

【讨论】:

  • 嗨,这正是正在发生的事情,你建议我如何解决这个问题或修复这个问题。恐怕我正在使用的 sdo 对象只有一个 movenext 函数。
  • @david - 很难回答,因为您只发布了部分代码,所以我只是带您了解正在发生的事情。如果您确定只有 6004 条记录,则从 0 开始并在每个循环中递增一次。不需要 if 语句将其设置回 0。如果您完成了循环并且没有达到目标,只需在最后将其设置为最大值。
  • 它仍然给我一个错误它仍然得到 6006 所以它使用上面的代码。
  • @david - 您是否删除了所有其他 progBarSelectInvoices.Value++; 行。您应该只在代码中有该行一次。另外,我刚刚更新了应该避免这种情况的 if 语句。我没有意识到 maxCount 实际上是 6005 而不是 6004,因为您的记录数是 6004,而 maxCount 比这大 1。
猜你喜欢
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-18
  • 1970-01-01
  • 2019-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多