c# - 进度条超过最大值

标签 c# winforms

使用++操作递增时,进度条超过最大值。在下面的代码中,我有一个记录集,当它绕过循环时它的大小为 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();

最佳答案

如果我们回顾这里发生的事情,希望这能帮助您解决这个问题。让我们检查一下当您进入第 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 语句中执行前置或后置增量语句,因为这会使代码难以阅读。在这种情况下,我肯定会反对它。

如何修复
解决这个问题的一种方法——如果你确定你只有 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

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

关于c# - 进度条超过最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52247993/

相关文章:

c# - BitArray 改变范围内的位

c# - 检查用户输入是否在组合框项目中

winforms - 如何以编程方式与应用程序交互

c# - 根据文本确定自定义消息框的窗口大小

c# - Moq 枚举在 FirstOrDefault 上消失

c# - “RouteCollection”不包含 'MapMvcAttributeRoutes' 的定义

c# - 线程问题-产生多个线程的最佳方法

c# - 从具有两种类型的对象的列表中获取 ComboBox 选定值,并且组合框仅显示其中一种

C# 文本框按键控件帮助

c# - 从枚举中填充复选框列表