进度栏超过最大值

时间:2018-09-09 19:31:33

标签: c# winforms

使用++操作递增值时,进度条超过最大值。在下面的代码中,我有一个记录集,当它绕着循环运行时,它的大小为6004,即使我在到达值++时将if语句陷阱以将进度条重置为零,也设法将其记录为6006。隐藏面板。

    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();

1 个答案:

答案 0 :(得分:4)

希望,如果我们逐步了解此处发生的情况,这将有助于您解决此问题。让我们检查一下进入6003rd循环时会发生什么。 我现在假设progBarSelectInvoices.Value == 6002

这行是做什么的?

progresbarValue = progBarSelectInvoices.Value++;

最后。 progresbarValue == 6004progBarSelectInvoices == 6003

progresbarValue不再使用,因此可能只是被丢弃,但不确定

然后,我们跳下来做一堆其他事情,然后敲到这一行:

progressCount = progBarSelectInvoices.Value;

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

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

因此,如果maxCount == 6004比现在的第一部分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语句中执行前置或后置增量语句,因为这会使代码难以阅读。在这种情况下,我绝对不建议这样做。

如何修复
解决此问题的一种方法-如果您确定只有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++;

然后,您可以在循环末尾取消if / else业务,该业务将检查maxCount并重置进度条或对其进行递增。

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

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